如何为Laravel Reverb配置Nginx以实现WebSocket并解决SSL连接失败问题
看起来你在Ubuntu环境下用Nginx配置Laravel Reverb的SSL时,碰到了WebSocket连接失败的问题,咱们一起来理清楚问题所在并解决它。
你当前的配置情况
Supervisor配置(用于管理Reverb进程)
配置文件路径:/etc/supervisor/conf.d/websockets.conf
[program:websockets-l11] command=/usr/bin/php /var/www/l11/artisan reverb:start numprocs=1 autostart=true autorestart=true user=ubuntu
Nginx配置
server { root /var/www/l11/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; index index.php; server_name l11.example.com; charset utf-8; location / { try_files $uri $uri/ /index.php?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location /websocket { proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_set_header Scheme $scheme; proxy_set_header SERVER_PORT $server_port; proxy_set_header REMOTE_ADDR $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_pass http://0.0.0.0:8080; } listen 80; # managed by Certbot listen 443 ssl http2; # managed by Certbot ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot }
你遇到的错误信息
echo-bLibrbhu.js:8 WebSocket connection to 'wss://l11.example.com:8080/app/lkak9yjwbphvj8kwlzav?protocol=7&client=js&version=8.4.0-rc2&flash=false' failed
问题分析
从错误信息能看出来,你的前端代码直接尝试通过wss://l11.example.com:8080连接WebSocket,但Reverb本身是运行在非SSL的8080端口上的,而且这个端口通常不会对外暴露SSL服务。正确的做法应该是让WebSocket请求先经过Nginx的443端口(已经配置了SSL),再由Nginx反向代理到Reverb的8080端口。
解决方案
1. 调整Laravel相关配置
打开
config/reverb.php,确保以下配置正确:'host' => env('REVERB_HOST', '0.0.0.0'), 'port' => env('REVERB_PORT', 8080), 'scheme' => env('REVERB_SCHEME', 'http'),这里
scheme设为http就好,因为Nginx会处理SSL层。打开
config/broadcasting.php,修改pusher配置项(Reverb兼容Pusher协议):'pusher' => [ 'driver' => 'pusher', 'key' => env('PUSHER_APP_KEY'), 'secret' => env('PUSHER_APP_SECRET'), 'app_id' => env('PUSHER_APP_ID'), 'options' => [ 'cluster' => env('PUSHER_APP_CLUSTER'), 'host' => env('REVERB_HOST', '127.0.0.1'), 'port' => env('REVERB_PORT', 8080), 'scheme' => 'http', 'encrypted' => true, 'useTLS' => true, 'wsHost' => env('APP_URL', 'l11.example.com'), 'wsPort' => 443, 'wssPort' => 443, 'path' => '/websocket/app', ], ],重点是
wsHost设为你的域名,wsPort和wssPort都用443,path指向Nginx配置的/websocket路径加上/app(Reverb的默认路径)。
2. 确保前端连接地址正确
如果是手动写的WebSocket连接代码,不要指定8080端口,应该用类似下面的格式:
const socket = new WebSocket('wss://l11.example.com/websocket/app/your-key-here?protocol=7&client=js&version=8.4.0-rc2&flash=false');
3. 重启相关服务
重启Supervisor,确保Reverb进程正常运行:
sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start websockets-l11 # 检查进程状态 sudo supervisorctl status websockets-l11验证Nginx配置并重启:
sudo nginx -t sudo systemctl restart nginx
备注:内容来源于stack exchange,提问作者Jhordy Said Barrera

