要在swoole中实现websocket消息推送,必须让服务端具备主动向客户端发送数据的能力;需启用swoole扩展并安装think-swoole,配置swoole.php开启websocket模块,创建wshandler事件处理类,定义websocket.php路由映射,最后通过php think swoole start启动服务。

要在Swoole中实现WebSocket消息推送,必须让服务端具备主动向客户端发送数据的能力,而不是仅响应客户端请求;否则所有消息都依赖前端轮询或长连接假实时,既耗资源又延迟高。
启用Swoole扩展并安装think-swoole(ThinkPHP 6项目)
这一步是整个WebSocket服务的底层前提,缺一不可。若PHP未加载swoole扩展,后续所有配置都会失败。
执行php -m | grep swoole检查扩展是否已启用;无输出说明未安装。
Linux下安装命令为:pecl install swoole,安装完成后在php.ini中添加extension=swoole并重启PHP服务。
【务必确认Swoole版本与ThinkPHP 6兼容】:推荐使用Swoole 4.8+或5.x,低版本可能不支持协程WebSocket处理器。
项目根目录执行:composer require topthink/think-swoole,该包提供框架级集成能力,非可选依赖。
配置swoole.php开启WebSocket模块
此配置决定服务是否真正识别并响应WebSocket握手请求,漏配或路径错误将导致客户端连接直接被拒绝。
打开config/swoole.php,确保包含以下三项关键设置:
'websocket' => ['enabled' => true] —— 必须设为true,否则模块不激活。
'handler' => \app\listener\WsHandler::class —— 指向你自定义的事件处理类,类名需与实际文件路径严格一致。
'route_file' => app_path() . 'websocket.php' —— 路径必须真实存在且可读,框架会按此路径加载路由映射表。
创建WebSocket事件处理类
该类是消息分发的核心枢纽,必须继承\think\swoole\WebSocket或实现对应接口,否则框架无法调用其生命周期方法。
执行命令生成监听器:php think make:listener WsHandler。
ThinkPHP 8.1.0 正式发布,深度优化路由与验证机制,完美兼容 PHP 8.4。本版本修复了数组路由配置异常,新增枚举值校验与高级数组验证功能,支持路由分类默认处理。作为高性能 PHP 框架的最新迭代,它延续了简洁实用的设计原则,提供更稳定的底层架构与更流畅的开发体验,助力开发者快速构建现代化 Web 应用与企业级系统。
编辑app/listener/WsHandler.php,在onOpen方法中加入用户身份校验逻辑(如解析token、查询Redis中的用户状态),避免未授权连接占用fd资源。
在onMessage中调用$this->send($fd, $data)实现单播,或$this->broadcast($data)广播——注意broadcast默认推送给所有连接,不含当前$fd。
【onClose中必须清理在线状态】:例如从Redis删除user_id → fd映射,否则后续向该fd推送会失败并抛出警告。
配置websocket.php路由映射文件
这个文件定义“客户端发什么类型消息 → 后端哪个监听器处理”,它不参与连接建立,但决定业务消息能否被正确分发。
在app/websocket.php中返回一个关联数组,例如:
return [ 'chat.send' => \app\listener\ChatSendListener::class, 'order.update' => \app\listener\OrderUpdateListener::class ];
若客户端发送{"type": "order.update", "data": {...}},框架会自动实例化OrderUpdateListener并调用其handle方法。
路径写错、文件不存在、返回值非数组,都会导致消息类型无法匹配,静默丢弃无日志。
启动WebSocket服务
第一步:停止所有PHP-FPM进程,【绝对不可用PHP-FPM运行WebSocket服务】,否则连接立即断开且无错误提示。
第二步:执行php think swoole start启动服务,默认监听0.0.0.0:8080(具体端口以swoole.php中port配置为准)。
第三步:用浏览器开发者工具Console测试连接:const ws = new WebSocket('ws://127.0.0.1:8080');,观察onopen是否触发。
第四步:服务启动后,终端应持续输出worker进程PID及日志,若秒退请检查swoole.php中daemonize设为false便于调试。










