Laravel11中ReactPHP Socket TcpServer客户端连接失败问题求助
问题原因
你用的React\Socket\TcpServer是原始TCP协议服务端,但WebSocket客户端发起的不是单纯的TCP连接——它会先发送HTTP升级请求,要求将连接升级为WebSocket协议。你的服务端没有处理这个握手流程,客户端收不到符合要求的响应,就会立即断开连接,所以出现了连接后马上结束、关闭的日志。
解决方案
直接使用ReactPHP官方提供的WebSocket组件来处理WebSocket连接,它会自动完成握手流程:
1. 安装WebSocket组件
执行Composer命令安装依赖:
composer require react/websocket
2. 修改命令代码
替换原有的TcpServer为WebSocketServer,调整事件监听逻辑:
<?php namespace App\Console\Commands; use Illuminate\Console\Command; use React\EventLoop\Loop as EventLoop; use React\Socket\TcpServer; use React\WebSocket\Server as WebSocketServer; use React\WebSocket\ConnectionInterface; class SocketTest extends Command { protected $signature = 'socket:test'; protected $description = 'Run asynchronous WebSocket server'; public function handle() { $loop = EventLoop::get(); // 先创建TCP服务 $tcpServer = new TcpServer('0.0.0.0:8001', $loop); // 基于TCP服务创建WebSocket服务 $webSocketServer = new WebSocketServer($loop); // 监听WebSocket连接事件 $webSocketServer->on('connection', function (ConnectionInterface $connection) { $remoteAddr = $connection->getRemoteAddress(); echo "{$remoteAddr} WebSocket 连接建立\n"; // 接收客户端消息 $connection->on('message', function ($message) use ($connection, $remoteAddr) { echo "收到{$remoteAddr}的消息:{$message}\n"; // 回复消息 $connection->send("已收到:{$message}"); }); $connection->on('close', function () use ($remoteAddr) { echo "{$remoteAddr} WebSocket 连接关闭\n"; }); $connection->on('error', function (\Exception $e) use ($remoteAddr) { echo "{$remoteAddr} 连接出错:{$e->getMessage()}\n"; }); }); // 将TCP服务的连接转发给WebSocket服务处理 $tcpServer->on('connection', [$webSocketServer, 'handleConnection']); echo "WebSocket服务已启动,监听 0.0.0.0:8001\n"; $loop->run(); } }
3. 测试连接
重新执行php artisan socket:test启动服务,再用WebSocket Test Client连接ws://127.0.0.1:8001,就能正常建立连接并收发消息了。
补充:手动实现WebSocket握手(不推荐)
如果不想依赖额外组件,需要手动解析客户端的HTTP升级请求,生成符合WebSocket规范的响应:
- 解析客户端发送的
Sec-WebSocket-Key字段 - 用该Key加上固定字符串
258EAFA5-E914-47DA-95CA-C5AB0DC85B11,做SHA-1哈希后再Base64编码 - 返回HTTP 101响应,包含
Upgrade: websocket和Sec-WebSocket-Accept头 - 后续还要处理WebSocket的帧编码/解码(比如掩码处理)
这个过程繁琐且容易出错,所以优先推荐使用官方WebSocket组件。
内容的提问来源于stack exchange,提问作者K i
相关产品推荐
相关产品推荐

