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

Laravel Websockets连接失败:WebSocket连接建立前已关闭

Laravel WebSocket连接失败排查指南(针对beyondcode/laravel-websockets)

错误信息

WebSocket connection to '' failed: WebSocket is closed before the connection is established.

相关代码与配置

1. TestSocketHandler.php

<?php

namespace App\Websocket\SocketHandler;


use Ratchet\ConnectionInterface;
use Ratchet\RFC6455\Messaging\MessageInterface;
use Ratchet\WebSocket\MessageComponentInterface;

class TestSocketHandler implements MessageComponentInterface
{

    function onOpen(ConnectionInterface $conn)
    {
        // TODO: Implement onOpen() method.
        dd($conn->httpRequest);
    }

    function onClose(ConnectionInterface $conn)
    {
        // TODO: Implement onClose() method.
    }

    function onError(ConnectionInterface $conn, \Exception $e)
    {
        // TODO: Implement onError() method.
    }

    public function onMessage(ConnectionInterface $conn, MessageInterface $msg)
    {
        // TODO: Implement onMessage() method.
    }
}

2. web.php路由配置

BeyondCode\LaravelWebSockets\Facades\WebSocketsRouter::webSocket('/socket/test', \App\Websocket\SocketHandler\TestSocketHandler::class);

3. .env环境配置

BROADCAST_DRIVER=pusher
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

PUSHER_APP_ID=livepost
PUSHER_APP_KEY=livepost_key
PUSHER_APP_SECRET=livepost_secret
PUSHER_HOST=
PUSHER_PORT=443
PUSHER_SCHEME=https
PUSHER_APP_CLUSTER=mt1

LARAVEL_WEBSOCKETS_SSL_LOCAL_CERT="/etc/letsencrypt/live/mydomain.com/fullchain.pem"
LARAVEL_WEBSOCKETS_SSL_LOCAL_PK="/etc/letsencrypt/live/mydomain.com/privkey.pem"
LARAVEL_WEBSOCKETS_SSL_PASSPHRASE=""
LARAVEL_WEBSOCKETS_PORT=6001

4. composer依赖

"pusher/pusher-php-server": "7.0.2",
"beyondcode/laravel-websockets": "^1.14"

5. Supervisor配置(/etc/supervisor/conf.d/websockets.conf)

[program:websockets]
process_name=%(program_name)s
command=sudo php artisan websockets:serve --port=8443
directory=/home/my-app/www
autostart=true
autorestart=true
user=root
redirect_stderr=true
stdout_logfile=/home/my-app/www/storage/logs/websockets.log

6. Supervisor运行状态

root@my-app:/etc/supervisor/conf.d# supervisorctl status
websockets                       RUNNING   pid 872475, uptime 1:41:26

已排查情况

  • laravel-websockets仪表盘可正常访问
  • WebSocket进程通过Supervisor正常运行
  • 已检查laravel.log和nginx error.log,未发现相关错误日志
  • 问题持续两天未解决

排查方向

1. 端口不一致问题

  • .env中配置LARAVEL_WEBSOCKETS_PORT=6001,但Supervisor启动命令指定--port=8443,端口不匹配会直接导致连接失败,需统一端口后重启WebSocket服务。
  • 检查服务器防火墙/安全组,确保当前使用的端口(6001或8443)已开放TCP流量。

2. SSL配置与启动方式冲突

  • 使用SSL证书时,启动WebSocket服务需明确添加--ssl参数,否则服务不会启用SSL,前端用wss协议连接会失败。修改Supervisor命令为:
    php artisan websockets:serve --port=8443 --ssl
    
  • 验证SSL证书路径正确性,确保root用户有权限读取证书文件(/etc/letsencrypt下的文件默认权限可能限制非root用户读取,当前用root启动需确认文件存在且可读)。

3. 代码逻辑阻塞

  • TestSocketHandler的onOpen方法中使用dd($conn->httpRequest)会中断连接流程,强制关闭连接。移除dd语句,替换为日志记录或正常连接处理逻辑后再测试。

4. Nginx反向代理配置(若使用)

  • 若前端通过Nginx反向代理访问WebSocket,需确保配置支持WebSocket升级,示例配置:
    location /socket/test {
        proxy_pass http://127.0.0.1:8443;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    
  • 注意代理端口需与WebSocket服务启动端口一致,若用SSL,Nginx的server块需配置HTTPS,同时WebSocket服务需启用SSL或由Nginx处理SSL后转发到HTTP服务。

5. 前端连接URL正确性

  • 确认协议:WebSocket服务启用SSL则用wss://yourdomain.com/socket/test,未启用则用ws://yourdomain.com/socket/test。
  • 确认端口:若Nginx监听443无需加端口;直接连接WebSocket服务需加上对应端口(如8443)。

日志位置与调试方法

1. WebSocket服务日志

  • Supervisor指定日志文件:/home/my-app/www/storage/logs/websockets.log,查看是否有启动或连接异常信息。若日志为空,可修改Supervisor配置去掉redirect_stderr=true,让错误输出到日志中。
  • 手动启动测试:停止Supervisor进程后,在项目目录执行php artisan websockets:serve --port=8443 --ssl,观察控制台实时输出,更容易发现错误。

2. Laravel日志增强

  • 在onError方法中添加日志记录,捕捉连接错误:
    function onError(ConnectionInterface $conn, \Exception $e)
    {
        \Log::error('WebSocket连接错误: ' . $e->getMessage(), ['trace' => $e->getTraceAsString()]);
        $conn->close();
    }
    
  • 在onOpen方法中添加日志,确认连接请求是否到达服务器:
    function onOpen(ConnectionInterface $conn)
    {
        \Log::info('新的WebSocket连接建立', ['conn_id' => $conn->resourceId]);
    }
    

3. 浏览器调试工具

  • 用浏览器开发者工具Network标签,筛选WS类型请求,查看请求头、响应头和错误详情,确认是否有HTTP错误码(如404、403),排查路由或权限问题。

内容的提问来源于stack exchange,提问作者Vüsal Hüseynli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 04:39:34