使用@socket.io/redis-emitter无法向@socket.io/redis-adapter服务端发事件
问题分析与解决
你遇到的核心问题是事件监听位置错误,同时代码存在冗余,可能还有版本兼容性问题,导致服务端无法接收Redis Emitter发送的事件。
问题点拆解
- 监听对象错误:你在单个
socket连接实例上监听time事件,但Redis Emitter通过io.emit()发送的事件是广播到Socket.io服务端实例(io对象),而非单个客户端连接的socket。 - Emitter代码冗余:
emitter.js中重复创建了Emitter实例,多余的实例无意义且可能干扰逻辑。 - 版本兼容性风险:如果
@socket.io/redis-adapter、@socket.io/redis-emitter与socket.io、redis客户端版本不匹配,会导致事件无法被正确解析转发。
修正后的代码
server.js
const { Server } = require("socket.io"); const { createClient } = require("redis"); const { createAdapter } = require("@socket.io/redis-adapter"); const io = new Server({ transports: ["websocket"] }); const pubClient = createClient({ url: "redis://localhost:6379" }); const subClient = pubClient.duplicate(); Promise.all([ pubClient.connect(), subClient.connect(), ]).then(() => { io.adapter(createAdapter(pubClient, subClient)); // 直接在io实例上监听来自Redis Emitter的time事件 io.on("time", (data) => { console.log("收到Emitter的时间事件:", data); // 若需转发给所有客户端,可添加此行 // io.emit("client-time", data); }); io.on("connection", (socket) => { console.log("socket connected"); // 如需监听客户端主动发送的time事件,保留以下代码 // socket.on("time", (data) => { // console.log("客户端发送的time数据:", data); // }); }); io.listen(3000); });
emitter.js
const { Emitter } = require("@socket.io/redis-emitter"); const { createClient } = require("redis"); const redisClient = createClient({ url: "redis://localhost:6379" }); redisClient.connect().then(() => { const io = new Emitter(redisClient); setInterval(() => { const now = new Date(); console.log("发送time事件:", now); io.emit("time", now); }, 5000); });
额外检查项
- 确认Redis服务正常运行,端口
6379可访问,无密码或配置正确的认证信息。 - 核对依赖版本匹配:
socket.io>= 4.0.0@socket.io/redis-adapter>= 7.0.0@socket.io/redis-emitter>= 5.0.0redis>= 4.0.0
- 用Redis CLI命令
redis-cli monitor实时查看事件流转:Emitter发送时会触发PUBLISH命令,服务端会有对应的SUBSCRIBE操作记录。
内容的提问来源于stack exchange,提问作者Saurabh Kumar
相关产品推荐
相关产品推荐

