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

Apache2搭配PHP Ratchet WebSocket Server无法连接问题求助

Apache反向代理Ratchet WebSocket连接失败排查

我使用PHP Ratchet编写了WebSocket服务器,已在Apache2中启用proxy、proxy_wstunnel、proxy_http模块,并配置了反向代理规则,但前端始终无法建立连接,Firefox提示“Firefox can’t establish a connection to the server at wss://www.xpatvoice.com:8080/”,其他浏览器结果一致。不清楚如何获取错误日志或错误码排查问题,也曾尝试错误的连接地址,均无效。


Apache网站配置

<VirtualHost *:443>
 DocumentRoot /var/www/mywebsite/pav/
 ServerName www.mywebsite.com
 ServerAlias mywebsite.com

 RewriteEngine on
 ProxyPass /wss2/ ws://www.mywebsite.com:8080


 <Directory /var/www/mywebsite/pav/>
 DirectoryIndex index.php
 AllowOverride All
 Order allow,deny
 Allow from all
 </Directory>
</VirtualHost>

前端初始连接代码

var socket = new WebSocket('wss://www.mywebsite.com:8080');

尝试过的错误连接地址

var socket = new WebSocket('wss://www.mywebsite.com/wss2/:8080');

Socket类代码

namespace MyApp;

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;


class Socket implements MessageComponentInterface {

    public function __construct()
    {
        $this->clients = new \SplObjectStorage;
        $this->users = [];
        $this->inqs = [];
    }

    public function onOpen(ConnectionInterface $conn) {

        // Store the new connection in $this->clients
        $this->clients->attach($conn);

        echo "New connection! ({$conn->resourceId})\n";
        //echo $conn->httpRequest->headers["X-Forwarded-For"][0];
                
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        
        $data = json_decode($msg);
        $userinfo = json_decode($data->userinfo,true);

       if(isset($userinfo["userId"]) && $data->action == "userLogin"){
                $userID = $userinfo["userId"];
                $this->users[$userID]["conn"] = $from;
                $this->users[$userID]["role"] = $userinfo["role"]; 
                echo "attached user $userID\n";
           
           // NOTIFY INQUISITORS OF ADMIN LOGIN
                if($userinfo["role"] < 3){
                    foreach($this->inqs as $inq => $client){
                        $message["action"] = "adminLogon";
                        $client->send(json_encode($message));
                    }
                 } 
       }
        
        if(isset($userinfo["userId"]) && $data->action == "adminReply"){
            
            $this->inqs[$data->to]->send($msg);
            
        }
        
           if(isset($userinfo["tempuser"]) && $data->action == "enquiry"){
                $userID = $userinfo["tempuser"];
                $this->inqs[$userID] = $from;
                echo "attached inquisitor $userID\n";
          }
        
        if(isset($userinfo["tempuser"])){
            
            foreach($this->users as $userid => $user){
                if($user["role"] < 3){
                    $user["conn"]->send($msg);
                }
            }
            echo "message from inquisitor\n";
         }
        

    }

    public function onClose(ConnectionInterface $conn) {

      $this->clients->detach($conn);

    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
    }
}

模块启用情况

执行以下命令确认模块已启用:

sudo a2enmod proxy
# 输出: Module proxy already enabled

sudo a2enmod proxy_wstunnel
# 输出: Module proxy_wstunnel already enabled

sudo a2enmod proxy_http
# 输出: Module proxy_http already enabled

当前Apache版本:2.4.41


排查与解决步骤

  1. 修正前端连接地址
    配置中ProxyPass将/wss2/代理到ws://www.mywebsite.com:8080,前端应使用wss://www.mywebsite.com/wss2/,无需添加8080端口(Apache会自动转发):

    var socket = new WebSocket('wss://www.mywebsite.com/wss2/');
    
  2. 完善Apache配置

    • 补充ProxyPassReverse规则,确保反向代理完整性:
      ProxyPass /wss2/ ws://localhost:8080/
      ProxyPassReverse /wss2/ ws://localhost:8080/
      
    • 建议使用localhost代替域名,避免DNS解析问题
    • Apache 2.4版本替换旧版目录权限语法:
      <Directory /var/www/mywebsite/pav/>
          DirectoryIndex index.php
          AllowOverride All
          Require all granted
      </Directory>
      
  3. 检查Ratchet服务器状态

    • 确保Ratchet服务器监听0.0.0.0:8080(允许外部访问)或127.0.0.1:8080(仅本地Apache转发)
    • 确认服务器已启动,且防火墙未拦截8080端口
  4. 查看错误日志

    • Apache错误日志路径一般为/var/log/apache2/error.log,执行tail -f /var/log/apache2/error.log实时查看
    • Ratchet服务器启动终端会输出日志,可直接查看或重定向到日志文件
  5. 完善错误处理逻辑
    为Socket类的onError方法添加日志输出,便于排查连接错误:

    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "Error occurred: {$e->getMessage()}\n";
        $conn->close();
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 12:21:10