安裝hyperf/websocket-server組件
composer require hyperf/websocket-server
websocket服務配置 config/autoload/server.php
<?php
declare(strict_types=1);
use Hyperf\Server\Event;
use Hyperf\Server\Server;
use Swoole\Constant;
return [
'mode' => SWOOLE_PROCESS,
'servers' => [
[
'name' => 'http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9501,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
],
],
//websocket服務配置
[
'name' => 'ws',
'type' => Server::SERVER_WEBSOCKET,
'host' => '0.0.0.0',
'port' => 9504,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_HAND_SHAKE => [Hyperf\WebSocketServer\Server::class, 'onHandShake'],
Event::ON_MESSAGE => [Hyperf\WebSocketServer\Server::class, 'onMessage'],
Event::ON_CLOSE => [Hyperf\WebSocketServer\Server::class, 'onClose'],
],
],
],
'settings' => [
Constant::OPTION_ENABLE_COROUTINE => true,
Constant::OPTION_WORKER_NUM => swoole_cpu_num(),
Constant::OPTION_PID_FILE => BASE_PATH . '/runtime/hyperf.pid',
Constant::OPTION_OPEN_TCP_NODELAY => true,
Constant::OPTION_MAX_COROUTINE => 100000,
Constant::OPTION_OPEN_HTTP2_PROTOCOL => true,
Constant::OPTION_MAX_REQUEST => 100000,
Constant::OPTION_SOCKET_BUFFER_SIZE => 2 * 1024 * 1024,
Constant::OPTION_BUFFER_OUTPUT_SIZE => 2 * 1024 * 1024,
// Task Worker 數量,根據您的服務器配置而配置適當的數量
'task_worker_num' => 2,
// 因為 `Task` 主要處理無法協程化的方法,所以這里推薦設為 `false`,避免協程下出現數據混淆的情況
'task_enable_coroutine' => false,
],
'callbacks' => [
Event::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'],
Event::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'],
Event::ON_WORKER_EXIT => [Hyperf\Framework\Bootstrap\WorkerExitCallback::class, 'onWorkerExit'],
// Task callbacks
Event::ON_TASK => [Hyperf\Framework\Bootstrap\TaskCallback::class, 'onTask'],
Event::ON_FINISH => [Hyperf\Framework\Bootstrap\FinishCallback::class, 'onFinish'],
],
];
創建websocket服務控制器 app/Controller/WebSocketController.php
<?php
declare(strict_types=1);
namespace App\Controller;
use Hyperf\Contract\OnCloseInterface;
use Hyperf\Contract\OnMessageInterface;
use Hyperf\Contract\OnOpenInterface;
use Swoole\Http\Request;
use Swoole\Server;
use Swoole\Websocket\Frame;
use Swoole\WebSocket\Server as WebSocketServer;
class WebSocketController implements OnMessageInterface, OnOpenInterface, OnCloseInterface
{
public function onMessage($server, Frame $frame): void
{
echo "message\n";
$server->push($frame->fd, 'Recv: ' . $frame->data);
}
public function onClose($server, int $fd, int $reactorId): void
{
var_dump('closed');
}
public function onOpen($server, Request $request): void
{
echo "open\n";
$server->push($request->fd, 'Opened');
}
}
配置websocket路由 config/route.php
<?php
declare(strict_types=1);
use Hyperf\HttpServer\Router\Router;
use App\Middleware\Middleware1;
use App\Middleware\Middleware2;
Router::addServer('ws', function () {
Router::get('/', 'App\Controller\WebSocketController');
});
Router::addRoute(['GET', 'POST', 'HEAD'], '/', 'App\Controller\IndexController@index');
Router::get('/favicon.ico', function () {
return '';
});
啟動hyperf服務
php bin/hyperf.php start
websocket客戶端測試文件(websocket.html)
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket測試</title>
<script>
function initWebSocket(wsUri) {
var websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
console.log('連接建立中... '+wsUri);
};
websocket.onclose = function(evt) {
console.log('連接關閉中...', evt);
};
websocket.onmessage = function(evt) {
console.log('收到來自服務端的消息:', evt.data);
};
websocket.onerror = function(evt) {
console.log('發生錯誤...', evt);
};
return websocket;
}
var websocket = initWebSocket("ws://118.195.173.53:9504");
var msg, i = 0;
var loop = setInterval(function(){
msg = "Hello " + (i++);
if(websocket.readyState == WebSocket.OPEN) {
websocket.send(msg);
console.log('已發送消息:' + msg);
} else {
clearInterval(loop);
console.log('連接已關閉,拜拜~');
}
}, 3000);
</script>
</head>
<body>
請按 F12 打開控制台查看消息
</body>
</html>
瀏覽器 console打印
連接建立中... ws://118.195.173.53:9504
websocket.html:17 收到來自服務端的消息: Opened
websocket.html:31 已發送消息:Hello 0
websocket.html:17 收到來自服務端的消息: Recv: Hello 0
websocket.html:31 已發送消息:Hello 1
websocket.html:17 收到來自服務端的消息: Recv: Hello 1
websocket.html:31 已發送消息:Hello 2
websocket.html:17 收到來自服務端的消息: Recv: Hello 2
瀏覽器 network > ws > messages 打印
Hello 1 7
01:28:36.098
Recv: Hello 1 13
01:28:36.145
Hello 2 7
01:28:39.098
Recv: Hello 2 13
01:28:39.295
Hello 3 7
01:28:42.097
Recv: Hello 3