Laravel 的 Pusher 驱动私有部署失败因默认连接外网 api.pusher.com,内网超时;Workerman 需实现 /broadcasting/auth 签名认证、HTTP 事件推送与 WebSocket 双通道,并严格对齐 Laravel 广播协议字段、header 和签名规则。

为什么 Laravel 的 pusher 驱动在私有部署时跑不起来
因为 Pusher 是 SaaS 服务,BROADCAST_DRIVER=pusher 默认会往 api.pusher.com 发请求,内网或无外网环境直接超时或报 cURL error 6: Could not resolve host。本地用 log 或 redis 驱动又不支持客户端实时接收——这不是“广播”,只是日志或消息暂存。
Workerman 作为广播服务端要解决什么核心问题
它得替代 Pusher 的 HTTP API + WebSocket 双通道能力:既要能被 Laravel 通过 HTTP POST 接入(比如 BroadcastController@authenticate 和事件推送),又要让前端用原生 WebSocket 或 Socket.io-client 连上收消息。关键不是“启动 Workerman”,而是让它和 Laravel 的广播协议对齐。
- 必须实现
/broadcasting/auth路由,返回符合 Laravel 签名规则的{"auth":"xxx.xxx"} - 必须监听
APP_KEY加密的 channel 认证(Laravel 默认用sha256+APP_KEY签名) - 不能直接用
socket.io的默认命名空间,Laravel 的private-/presence-channel 名需原样透传
如何让 Laravel 把事件推给 Workerman 而不是 Pusher
靠自定义广播驱动:实现 Illuminate\Broadcasting\Broadcasters\Broadcaster 接口,重写 auth 和 broadcast 方法。重点不是写新驱动类,而是绕过 Laravel 内置的 HTTP 客户端封装,直接用 file_get_contents 或 cURL 向 Workerman 的 HTTP 接口发 POST。
-
broadcast()方法里,把$channels、$event、$payload组成标准 JSON,POST 到http://127.0.0.1:2120/api/broadcast(Workerman 自建的接收端) -
auth()方法里,别调PusherBroadcaster::auth(),改用手算签名:hash_hmac('sha256', $channelName.':'.$socketId, config('app.key')),拼成{"auth": "...:..."} - 务必在
config/broadcasting.php的connections下注册新驱动,例如'workerman' => ['driver' => 'workerman']
Workerman 服务端最容易漏掉的三个校验点
90% 的连接失败不是因为端口不通,而是协议细节没对齐。前端连不上 ws://127.0.0.1:2120,先查这三项:
- HTTP 认证接口返回的
Content-Type必须是application/json,Laravel 的PusherBroadcaster源码里硬判了这个 header - WebSocket 握手时,Workerman 必须响应
Sec-WebSocket-Accept,用base64_encode(sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true))计算,不能直接 echo - 广播消息体必须是纯 JSON 字符串,且字段名严格为
event、channel、data,Laravel 的Echo客户端不认type或payload
Workerman 不是开箱即用的 Pusher 替代品,它只提供 socket 底层,所有 Laravel 广播语义都得手动桥接。少一个字段、错一个 header、漏一次签名,前端就永远卡在 connecting...。











