Socket IO + Redis部署异常:服务端未接收Redis频道消息
我之前也踩过Socket.io + Redis跨服务通信的坑,结合你描述的情况,这里有几个针对性的排查方向可以试试:
核对Socket.io与Redis适配器的版本兼容性
Socket.io的Redis适配器有版本绑定要求——比如旧版的socket.io-redis只适配Socket.io 2.x,如果你用的是Socket.io 4.x及以上,必须用@socket.io/redis-adapter。先确认你的依赖版本是否匹配:# 查看Node.js项目的依赖版本 npm list socket.io @socket.io/redis-adapter redis验证PHP发送的Redis消息格式
Socket.io的Redis适配器只识别特定格式的消息,不是随便发字符串就能触发事件的。正常格式是JSON数组,结构为["事件名", [参数列表], "命名空间"]。你可以用redis-cli的监控命令,把PHP发送的消息和Socket.io自身发送的消息做对比:# 启动Redis监控,捕获所有消息 redis-cli MONITOR比如Socket.io正常发送的消息可能是:
*3\r\n$4\r\npubsub\r\n$9\r\nemit#test\r\n$27\r\n["chat", ["hello"], "/"],如果PHP发的格式偏离这个结构,Socket.io会直接忽略。确认命名空间与房间的一致性
如果你的Socket.io服务用了自定义命名空间(比如/chat),PHP发送消息时必须指定完全相同的命名空间参数,否则适配器不会把消息转发给对应的Socket.io实例。另外如果涉及房间,也要确保PHP发送时指定了正确的房间名。检查Docker环境下的Redis配置细节
虽然你说连接正常,但要确认Node.js和PHP的Redis客户端是否用了相同的数据库编号(默认是0)、是否设置了相同的密码(如果Redis有认证)。另外Docker容器内的Redis地址要统一用容器名/网络别名,避免因为网络隔离导致消息虽然到了Redis,但Socket.io的适配器没监听对的通道。开启Socket.io的调试日志
在Node.js服务入口添加调试环境变量,能看到适配器接收Redis消息的详细日志,直接定位问题环节:// 在项目开头添加 process.env.DEBUG = "socket.io:*";重启服务后看控制台输出,如果没有Redis消息接收的日志,说明适配器没监听到消息;如果有日志但没触发事件,那大概率是格式或命名空间不匹配。
内容的提问来源于stack exchange,提问作者Vincent

