Laravel Websockets部署EC2反向代理SSL连接失败问题求助
本地功能正常、部署后提示Channels current state is unavailable、wss连接6001端口失败,是Laravel Websockets部署到AWS EC2的高频问题,按以下步骤逐一排查即可解决:
1. 先确认基础服务可用性
- 登录EC2实例,手动执行
php artisan websockets:serve启动服务,观察启动日志是否有报错。注意启动时不要绑定127.0.0.1,默认监听0.0.0.0:6001才能同时接收本地代理和外部请求。 - 服务器本地执行测试命令:
curl http://127.0.0.1:6001/health,正常返回ok才代表服务本身运行正常;如果返回连接拒绝/超时,先排查服务启动状态、端口监听是否正常。 - 检查两层网络规则:
- AWS EC2安全组入方向规则,如果直连6001端口需要放开6001的TCP入站,如果走443反向代理要确认本地回环访问不受限
- 服务器本地防火墙(ufw/firewalld)没有阻止6001或443端口的访问
2. 修正Apache反向代理配置错误
你当前的代理配置存在3个核心错误,是连接失败的主要原因:
- 路径匹配规则错误:规则
^/ws/(.*)仅匹配带/ws/前缀的请求,但Pusher客户端的默认请求路径为/app/xxx、/health、/apps等,根本不会命中websocket代理规则 - 代理协议错误:本地启动的Websocket服务默认是未加密的
ws协议,你配置的wss://127.0.0.1:6001会导致Apache和本地服务SSL握手失败,应该使用ws:// - 代理规则缺失:仅配置了
ProxyPassReverse没有配置对应的正向代理规则,会导致仪表盘拉取统计数据、健康检查这类普通HTTP请求转发失败
替换为以下可直接使用的配置:
<IfModule mod_ssl.c> <VirtualHost *:443> ServerAdmin admin@mydomain.net ServerName socket.mydomain.net ServerAlias www.socket.mydomain.net RewriteEngine On ProxyPreserveHost On ProxyRequests Off # 代理Websocket长连接请求 RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule /(.*) ws://127.0.0.1:6001/$1 [P,L] # 代理普通HTTP请求 RewriteCond %{HTTP:Upgrade} !=websocket [NC] RewriteRule /(.*) http://127.0.0.1:6001/$1 [P,L] ProxyPassReverse / http://127.0.0.1:6001/ DocumentRoot /var/www/html/websocket/public <Directory "/var/www/html/websocket"> AllowOverride all Require all granted </Directory> Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/socket.mydomain.net/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/socket.mydomain.net/privkey.pem </VirtualHost> </IfModule>
配置修改完成后执行以下命令生效:
- 启用Apache依赖模块:
a2enmod proxy proxy_wstunnel proxy_http rewrite - 重启Apache服务:
systemctl restart apache2
3. 同步修改Laravel侧配置
走443端口反向代理后,不需要再访问6001端口,修改项目根目录.env文件的对应配置项:
PUSHER_HOST=socket.mydomain.net PUSHER_PORT=443 PUSHER_SCHEME=https
同时确认config/broadcasting.php中pusher驱动的use_tls参数设为true,Laravel Websockets自带仪表盘的配置(config/websockets.php)也要和上述参数保持一致,最后执行php artisan config:clear清除配置缓存。
4. 连通性验证
配置生效后先在本地终端执行curl https://socket.mydomain.net/health,返回ok即代表反向代理配置正常。此时打开Websocket仪表盘,浏览器发起的请求会变为wss://socket.mydomain.net/app/xxx走标准443端口,不会再出现6001端口连接失败的报错。
如果选择直连6001端口不走反向代理,需要在
config/websockets.php的ssl配置项中填写Let's Encrypt证书的绝对路径,同时确保6001端口在安全组、防火墙中放开。生产环境更推荐443反向代理方案,避免非标准端口被用户侧防火墙拦截。
内容的提问来源于stack exchange,提问作者kianoosh Azarvandi

