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

JavaScript无法连接Laravel+Ratchet搭建的安全WebSocket服务器求助

开发环境
  • OS: Microsoft Windows 10
  • PHP框架: Laravel 8.0
  • PHP版本: 7.4
  • Websocket服务端: cboden/ratchet 0.4.3
  • 集成环境: WAMP server 3.2.0 (Apache 2.4.41)
  • 测试浏览器: Firefox 91.0.1 (64位) / Chrome
问题说明

我新建了一个Laravel应用来实现安全WebSocket服务端,客户端侧(Laravel blade文件)使用原生JavaScript发起连接。目前WebSocket服务端运行状态正常,但浏览器无法成功建立连接,报错截图如下:
报错截图

我已尝试使用带端口、不带端口的不同URL连接,均未生效。我使用openssl.exe工具生成了SSL证书和私钥文件,放置在命令执行目录下用于测试。

安全WebSocket服务端handle方法代码

public function handle()
{
   $loop   = Factory::create();
   $webSock = new SecureServer(
      new Server('0.0.0.0:8090', $loop),
      $loop,
      array(
         'local_cert'        => 'certificate.crt', 
         'local_pk'          => 'private.key', 
         'allow_self_signed' => TRUE, 
         'verify_peer' => FALSE
      )
   );

   // Ratchet逻辑
   $webServer = new IoServer(
      new HttpServer(
         new WsServer(
            new WebSocketController()
         )
      ),
      $webSock
   );

   $loop->run();
}

httpd-ssl.conf虚拟主机配置

<VirtualHost *:443>
  ServerName ssa
  DocumentRoot "d:/web/app/ssa/public"
  SSLEngine on
  
  SSLCertificateFile "${SRVROOT}/conf/certificate.crt"
  SSLCertificateKeyFile "${SRVROOT}/conf/private.key"

  SSLVerifyClient none
  SSLVerifyDepth 10

  <Directory "d:/web/app/ssa/public">
    Options +Indexes +Includes +FollowSymLinks +MultiViews
    AllowOverride All
    Require local
  </Directory>
  
  ProxyRequests Off 
  ProxyPass /wss/  ws://ssa:8090
</VirtualHost>

目前Apache的proxy_module、proxy_http_module、proxy_wstunnel_module模块均已启用,站点运行在HTTPS协议下。此前站点运行在HTTP+WS协议时所有功能正常,升级为HTTPS后出现WSS连接失败问题,请问我是否遗漏了相关配置?我的WebSocket服务端或Apache配置存在什么问题?


问题排查与解决方案

你当前的配置存在两处核心冲突,还有部分遗漏配置,按以下步骤修改即可修复:

  1. 移除Ratchet端的SSL配置
    你用Apache做WSS反向代理的场景下,不需要让Ratchet本身处理SSL加密,直接把Ratchet改成普通WS服务即可,由Apache统一做SSL卸载,修改handle方法代码:
public function handle()
{
   $loop   = Factory::create();
   // 去掉SecureServer封装,直接用普通Server
   $webSock = new Server('0.0.0.0:8090', $loop);

   // Ratchet逻辑保持不变
   $webServer = new IoServer(
      new HttpServer(
         new WsServer(
            new WebSocketController()
         )
      ),
      $webSock
   );

   $loop->run();
}
  1. 完善Apache反向代理配置
    你当前的ProxyPass缺少WebSocket协议升级的必要头配置,还有反向代理的回退规则,修改httpd-ssl.conf里的代理部分配置:
ProxyRequests Off 
# 开启WebSocket代理的头识别
RewriteEngine on
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/wss/(.*) ws://ssa:8090/$1 [P,L]

ProxyPass /wss/  ws://ssa:8090/
ProxyPassReverse /wss/  ws://ssa:8090/

修改后重启Apache服务,重启Ratchet的WebSocket服务。
3. 客户端连接地址确认
客户端直接连接wss://你的站点域名/wss/即可,不要加8090端口,所有请求走Apache的443端口代理即可。

如果确实需要让Ratchet本身处理SSL(不经过Apache代理直接对外暴露WSS端口),再做以下修改:

  • 把Apache的代理配置删除,客户端直接连接wss://你的域名:8090
  • 确认你执行Laravel命令启动WebSocket服务的工作目录下,确实存在certificate.crt和private.key文件,避免相对路径读取失败
  • 提前在浏览器里访问一次https://你的域名:8090,确认自签证书已经被浏览器信任,再发起WebSocket连接。

内容的提问来源于stack exchange,提问作者jgarcias

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 12:45:02