You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 02:18:17