Hyperf 3.0 WebSocket 服务

445 阅读1分钟

第一步:安装组件

composer require hyperf/websocket-server

第二步:配置文件配置 websocket 服务

<?php
// config/autoload/server.php    
'servers' => [
// websocket 服务
   [
       // 服务名称,注意这个名称,后续要用到
       'name'      => 'ws',
       'type'      => Server::SERVER_WEBSOCKET,
       'host'      => '0.0.0.0',
       'port'      => 9509,
       // TCP 连接
       'sock_type' => SWOOLE_SOCK_TCP,
       'callbacks' => [
           Event::ON_OPEN    => [\App\Controller\Server\WebSocketServerController::class'onOpen'],
           Event::ON_MESSAGE => [\App\Controller\Server\WebSocketServerController::class'onMessage'],
           Event::ON_CLOSE   => [\App\Controller\Server\WebSocketServerController::class'onClose'],
       ]
   ],
],

第三步:添加服务路由

// 注意:这里的 ws 要和配置文件中 websocket 服务的 name 值一样
Router::addServer('ws', function () {
    Router::get('/', \App\Controller\Server\WebSocketServerController::class);
});

第四步:创建 websocket 服务类

<?php
// App\Controller\Server\WebSocketServerController.php

namespace App\Controller\Server;

use Hyperf\Contract\OnCloseInterface;
use Hyperf\Contract\OnMessageInterface;
use Hyperf\Contract\OnOpenInterface;

class WebSocketServerController implements OnMessageInterface,OnOpenInterface,OnCloseInterface
{
    public function onOpen($server, $request): void
    {
        echo $request->fd . ' 号客户端已连接' . PHP_EOL;
        $server->push($request->fd, '服务端告诉你,你的id是: '.$request->fd);
    }

    public function onMessage($server, $frame): void
    {
        $data = json_decode($frame->data, true);
        $userId = (int)$data['userId'];
        $message = $data['message'];

        //实现对话
        if($frame->fd != $userId){
            $server->push($userId, $frame->fd.'号客户端对你说: '.$message);
        }else{
            //不填写id时发送给原客户端
            $server->push($frame->fd, '你对自己说: '.$message);
        }
    }

    public function onClose($server, int $fd, int $reactorId): void
    {
        echo $fd . '断开连接,处理线程是 ' . $reactorId . PHP_EOL;
    }

}

第五步:启动服务

php bin/hyperf.php start

第六步:创建 websocket 客户端

该文件位置随意

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>聊天室</title>
</head>
<body>
    <div>
        <input type="text" id="userId" placeholder="请输入ID">
        <input type="text" id="message" placeholder="请输入消息">
        <button onclick="sendMessage()">发送</button>
    </div>
    <div id="chatBox"></div>

    <script>
        // 创建 WebSocket 连接
        const ws = new WebSocket('ws://192.168.0.99:9509');

        // 监听 WebSocket 连接事件
        ws.onopen = function (event) {
            console.log('WebSocket 连接已打开');
        };

        // 监听 WebSocket 接收消息事件
        ws.onmessage = function (event) {
            const message = event.data;
            const chatBox = document.getElementById('chatBox');
            chatBox.innerHTML += '<p>' + message + '</p>';
        };
		//监听WebSocket 连接已关闭
		ws.onclose = function(event) {
		   console.log('WebSocket 连接已关闭');
		};
        // 发送消息
        function sendMessage() {
            const userId = document.getElementById('userId').value;
            const message = document.getElementById('message').value;
            const data = {
                userId: userId,
                message: message
            };
            ws.send(JSON.stringify(data));
			document.getElementById('userId').value = "";
			document.getElementById('message').value = "";
        }
    </script>
</body>
</html>

注意事项

除了要映射9501端口还要映射9509端口

image.png

结果

微信截图_20230802173522.png