Laravel自身不提供WebSocket服务器,php artisan serve仅支持HTTP,无法处理ws/wss连接;必须额外部署laravel-websockets或reverb等服务,并确保BROADCAST_DRIVER、前端broadcaster、key、wsHost/wsPort及Nginx代理配置全部严格对齐。

前端连不上 WebSocket,不是 Laravel Echo 写错了,而是后端根本没跑起兼容的服务,或者配置没对齐。
为什么 php artisan serve 启动后 Echo 一直 connecting
Laravel 自身不提供 WebSocket 服务器,php artisan serve 只是 HTTP 服务,它不处理 ws:// 或 wss:// 连接。Echo 尝试连接的地址(比如 ws://localhost:6001)必须由另一个独立进程提供服务。
- 常见错误:以为装了
laravel/echo和配了BROADCAST_DRIVER=redis就能连上 —— 其实这只是把事件扔进 Redis,没人监听并转发给浏览器 - 必须部署配套服务:本地开发用
laravel-websockets(PHP 实现)或reverb(Laravel ≥10.42 官方推荐),生产环境也可选 Pusher 或自建laravel-echo-server(Node.js) - 运行命令必须手动执行:
php artisan websockets:serve或php artisan reverb:start,且不能被 Ctrl+C 中断,否则前端立刻断连 - Docker 环境下注意网络模式:
localhost在容器里指向自己,前端要连宿主机就得用host.docker.internal或真实 IP
BROADCAST_DRIVER 和前端 broadcaster 必须严格匹配
驱动名错一个字母,Echo 就会按错误协议握手,静默失败,控制台可能只显示 WebSocket connection to 'ws://...' failed。
- 用
laravel-websockets:后端设BROADCAST_DRIVER=pusher,前端 Echo 初始化时broadcaster: 'pusher',key值必须和config/websockets.php里apps.0.key完全一致(默认是local,不是PUSHER_APP_KEY) - 用
reverb:后端设BROADCAST_DRIVER=reverb,前端broadcaster: 'reverb',key可任意(如'null'),但wsHost/wsPort必须对应REVERB_HOST/REVERB_PORT(默认127.0.0.1:8080) - 别混用:
BROADCAST_DRIVER=redis+ 前端broadcaster: 'pusher'是无效组合,Redis 只是消息中转,不是协议服务端 - 改完
.env后必须清缓存:php artisan config:clear,否则config('broadcasting.default')仍是旧值
频道名前后端不一致导致事件“发出去却收不到”
广播靠「频道名 + 事件名」双校验,任一环节拼错、大小写错、前缀漏掉,就静默丢弃,无报错。
- 后端返回
PrivateChannel('user.123'),前端监听必须写.private-user.123(开头带点,中间用短横),不能是user.123或.user.123 - 事件类用了
broadcastAs('order.updated'),前端就要.listen('order.updated', ...),否则默认按类名App.Events.OrderUpdated匹配(注意命名空间和驼峰) - 私有/存在频道需在
routes/channels.php显式授权,比如return $user && $user->id == $id;,返回false或抛异常都会拒绝连接 - 公共频道(
Channel)不用授权,但前端仍要加.public-前缀,如Channel('orders')→.public-orders
Nginx 反代 WebSocket 时最容易漏掉的三行配置
线上用 HTTPS 部署时,Nginx 默认会砍掉 Upgrade 和 Connection 头,导致 WebSocket 握手失败,状态码常是 400 或直接断开。
- 必须显式透传协议升级头:
proxy_http_version 1.1;、proxy_set_header Upgrade $http_upgrade;、proxy_set_header Connection "upgrade"; - 反代目标地址要写对:比如 wss://your.app → 转给
http://127.0.0.1:6001(laravel-websockets)或http://127.0.0.1:8080(reverb),不能写成https:// - SSL 证书必须有效,且前端
forceTLS: true,否则浏览器拒绝混合内容;本地开发用forceTLS: false,但wsHost不能写https://域名 - 防火墙要放行对应端口(6001 / 8080),云服务器安全组也得开,别只查 Nginx 配置
最常被忽略的是权限验证逻辑写在 routes/channels.php 里,但忘了返回布尔值;其次是 Nginx 没透传 Upgrade 头,现象是前端反复重连、抓包看到 400,却以为是代码问题。


















