在Hyperf3.1中实现WebSocket实时通信需四步:安装hyperf/websocket-server扩展并确认Swoole≥6.3.0;配置独立SERVER_WEBSOCKET服务实例,严格使用数组回调;编写继承WebSocketController的控制器,用@OnOpen/@OnMessage/@OnClose注解标记生命周期方法;最后通过浏览器WebSocket连接验证握手与消息收发是否正常。

要在Hyperf3.1中实现即时通讯类WebSocket实时通信,必须让服务端能主动向指定客户端推送消息、支持连接生命周期管理、可跨进程广播,并确保握手成功不被HTTP中间件拦截。缺任何一个环节,前端连上就断或收不到消息。
安装WebSocket核心组件
Hyperf默认不带WebSocket运行时能力,这一步不做,后续所有配置都无效。
执行命令安装官方扩展包:composer require hyperf/websocket-server
安装后检查Swoole是否启用:运行php --ri swoole,确认输出中包含version => 6.3.0或更高版本。若无输出或版本低于6.0,请先安装或升级Swoole扩展。
【必须确认 extension=swoole.so 已写入 php.ini,且未被;注释掉】
配置独立WebSocket服务器
不能复用HTTP服务器,必须声明一个类型为SERVER_WEBSOCKET的独立服务实例,否则ON_HAND_SHAKE事件不会触发。
打开config/autoload/server.php文件,在'servers'数组末尾追加以下配置:
'name' => 'ws',
'type' => \Hyperf\Server\Server::SERVER_WEBSOCKET,
'host' => '0.0.0.0',
'port' => 9502,
'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'],
],
注意:回调方法必须严格使用数组形式[Class::class, 'method'],不可用闭包或静态调用语法,否则Swoole无法反射执行。
编写WebSocket控制器处理连接事件
控制器必须继承\Hyperf\WebSocketServer\Annotation\WebSocketController,并用注解标记生命周期方法,否则框架无法识别事件入口。
创建文件app/Controller/WebSocketController.php,内容如下:
第一步:声明类并添加@AutoController和@WebSocketController注解
第二步:用@OnOpen注解标记连接建立方法,参数为Request $request,从中提取$request->get('uid')存入Context供后续使用
第三步:用@OnMessage注解标记消息接收方法,参数为Frame $frame,调用$this->sender->send($frame->fd, 'echo: '.$frame->data)回传
第四步:用@OnClose注解标记关闭方法,传入int $fd,可在此清理用户在线状态
这一步操作起来很简单,直接把文件拖进去就行,但注解名大小写必须完全匹配,@onopen或@Onopen都会导致事件失效。
验证WebSocket连接可用性
启动服务:php bin/hyperf.php start
在浏览器控制台执行测试连接:
const ws = new WebSocket('ws://127.0.0.1:9502?uid=1001');
ws.onopen = () => console.log('connected');
ws.onmessage = (e) => console.log('received:', e.data);
ws.send('hello');
若控制台打印connected且收到echo: hello,说明服务已就绪。若报错WebSocket is closed before the connection is established,大概率是server.php中callbacks键名拼写错误或ON_HAND_SHAKE未正确映射。


















