Ubuntu LAMP环境部署PHP Ratchet WebSocket服务连接失败求助
这种本地正常线上翻车的情况真的太闹心了!我之前部署WebSocket服务的时候也踩过不少类似的坑,给你梳理几个最可能的排查方向,按优先级来试:
1. 先确认端口是否对外开放
Ratchet默认会用自定义端口(比如8080),而DigitalOcean的Cloud Firewall和服务器本身的防火墙(ufw/iptables)都可能挡住这个端口:
- 登录DigitalOcean控制台,找到你的实例对应的Cloud Firewall,添加一条入站规则,允许TCP流量到你WebSocket用的端口(比如8080)。
- 登录服务器,执行
ufw status检查本地防火墙,如果端口没开放,用ufw allow 8080/tcp放行(记得重启ufw:ufw reload)。
2. 检查反向代理配置(关键!)
如果你的前端是通过Apache/Nginx访问的,直接让JS连WebSocket端口很容易出问题,最好用反向代理把WebSocket请求转发到Ratchet服务:
Nginx配置示例
location /ws { proxy_pass http://localhost:8080; # 这里要和你的Ratchet端口一致 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; }
配置完重启Nginx:systemctl restart nginx,前端就可以用wss://your-domain/ws(HTTPS环境)或ws://your-domain/ws连接,不用直接写端口。
Apache配置示例
先启用必要模块:
a2enmod proxy proxy_http proxy_wstunnel systemctl restart apache2
然后在虚拟主机配置里加:
ProxyPass "/ws" "ws://localhost:8080/ws" ProxyPassReverse "/ws" "ws://localhost:8080/ws"
3. 协议一致性问题(HTTPS必看)
如果你的线上站点用了HTTPS,前端绝对不能用ws://协议连接,必须换成wss://!浏览器的安全策略会阻止从HTTPS页面发起非加密的WebSocket请求,这是很多人忽略的点。
另外,确保反向代理已经正确处理SSL终止,不要让Ratchet直接处理证书(当然你也可以给Ratchet配置SSL,但用Web服务器做反向代理更省心)。
4. Ratchet服务的绑定地址
本地测试时绑定127.0.0.1没问题,但线上必须绑定0.0.0.0才能接收外部请求!检查你的Ratchet启动代码:
// 正确的写法,默认绑定0.0.0.0 $server = IoServer::factory( new HttpServer(new WsServer(new YourWebSocketHandler())), 8080 ); // 如果手动写了127.0.0.1,改成0.0.0.0 // $server = IoServer::factory(... , 8080, '0.0.0.0');
5. 确保Ratchet进程一直在运行
Ratchet是CLI进程,如果你只是手动启动后关闭SSH,进程会直接终止!用supervisor或者systemd来守护进程:
Supervisor配置示例
创建/etc/supervisor/conf.d/ratchet.conf:
[program:ratchet-websocket] command=php /var/www/your-project/websocket-server.php # 你的Ratchet启动文件路径 directory=/var/www/your-project user=www-data autostart=true autorestart=true stdout_logfile=/var/log/ratchet.log stderr_logfile=/var/log/ratchet-error.log
然后更新supervisor配置并启动:
supervisorctl reread supervisorctl update supervisorctl start ratchet-websocket
6. 跨域问题排查
虽然本地正常,但线上可能因为域名差异触发跨域限制。可以在Ratchet里添加CORS头,或者在反向代理里配置:
// 在Ratchet启动代码里添加CORS头 $server = IoServer::factory(...); $server->loop->addPeriodicTimer(0, function () use ($server) { foreach ($server->getConnections() as $conn) { $conn->sendHeaders([ 'Access-Control-Allow-Origin' => 'https://your-frontend-domain.com', // 不要用*,指定具体域名更安全 'Access-Control-Allow-Methods' => 'GET, POST, OPTIONS', 'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept' ]); } });
按这个顺序排查,大概率能找到问题!我之前就是因为DigitalOcean防火墙没开端口折腾了半天😂
内容的提问来源于stack exchange,提问作者Fussel

