如何在一台服务器上运行两个Laravel Echo Server(Socket.io)实例?
好问题!这种同一服务器上多环境共享WebSocket服务的场景其实挺常见的,咱们不用急着开第二个端口,先看看更优雅的解决方案:
不管是Socket.io还是Laravel Echo,都原生支持事件隔离的机制,不用额外启动新服务,就能让生产和测试环境的事件互不干扰。
方案1:给频道加环境前缀
这是最简单的方式,利用Laravel广播的频道前缀功能,让两个环境的事件频道名称完全区分开:
后端配置(Laravel)
在每个环境的.env文件里设置独立的频道前缀:
# 生产环境 .env BROADCAST_CHANNEL_PREFIX=production # 测试环境 .env BROADCAST_CHANNEL_PREFIX=staging
然后在config/broadcasting.php里,找到socket.io的配置部分,添加前缀配置:
'socketio' => [ 'driver' => 'socket.io', 'host' => env('SOCKET_IO_HOST', 'http://localhost'), 'port' => env('SOCKET_IO_PORT', 6001), 'prefix' => env('BROADCAST_CHANNEL_PREFIX', ''), ],
这样Laravel广播事件时,频道名会自动加上前缀——比如原来的order-updated频道,生产环境会变成production.order-updated,测试环境则是staging.order-updated,自然不会串台。
前端配置(Laravel Echo)
前端订阅频道时,要么手动带上前缀,要么在Echo初始化时配置前缀:
// 生产环境前端 window.Echo = new Echo({ broadcaster: 'socket.io', host: window.location.hostname + ':6001', prefix: 'production.' // 和后端前缀对应 }); // 订阅频道时直接写原名称即可 window.Echo.channel('order-updated').listen('OrderUpdated', (e) => { console.log(e.order); });
方案2:使用Socket.io命名空间
如果想做更彻底的隔离,可以利用Socket.io的**命名空间(Namespaces)**功能,让两个环境连接到WebSocket服务的不同命名空间,完全隔离事件流:
配置Laravel Echo Server
修改laravel-echo-server.json,添加两个环境的命名空间配置:
{ "port": "6001", // 其他基础配置... "namespaces": { "/production": { "authHost": "http://production.your-domain.com", "authEndpoint": "/broadcasting/auth" }, "/staging": { "authHost": "http://staging.your-domain.com", "authEndpoint": "/broadcasting/auth" } } }
每个命名空间可以单独配置认证地址和主机,适配不同虚拟主机的需求。
前端配置(Laravel Echo)
初始化Echo时指定对应的命名空间:
// 生产环境 window.Echo = new Echo({ broadcaster: 'socket.io', host: window.location.hostname + ':6001', namespace: '/production' // 指定命名空间 }); // 测试环境 window.Echo = new Echo({ broadcaster: 'socket.io', host: window.location.hostname + ':6001', namespace: '/staging' });
这样两个环境的WebSocket连接完全处于不同的命名空间,事件、认证逻辑都彻底隔离,不会互相干扰。
如果你的生产和测试环境需要完全独立的WebSocket服务(比如不同的Redis存储、日志文件、认证规则),那可以考虑启动第二个Laravel Echo Server实例,使用不同端口:
- 复制一份
laravel-echo-server.json作为测试环境的配置文件(比如laravel-echo-server-staging.json),修改端口为6002,并调整其他专属配置。 - 分别启动两个服务:
# 生产环境(默认配置,端口6001) laravel-echo-server start # 测试环境(指定配置文件,端口6002) laravel-echo-server start --config laravel-echo-server-staging.json
这种方式的优点是完全隔离,缺点是需要维护两个服务实例,占用更多服务器资源。
- 优先选择频道前缀或Socket.io命名空间方案:无需额外端口,配置简单,资源占用少,能满足绝大多数场景的隔离需求。
- 仅当两个环境需要完全独立的WebSocket服务时,再考虑启动第二个实例并使用不同端口。
内容的提问来源于stack exchange,提问作者xTheWolf

