我正在使用最新的 Socket.io 包,并且需要它与 Redis 适配器配合使用,以便在多个 Pod/服务器上正常工作。 Socket.io 工作正常,消息发送正确,房间被创建和删除等,但是在将其部署到服务器时我遇到了意外的行为,例如,并非所有用户总是收到消息。
我发现问题在于,该问题与它实际上并未使用 Redis 作为适配器这一事实有关。 例如,如果我在 redis-cli 中查找 RoomName
SCAN 0 MATCH *RoomName*
,我会得到一个空数组。
这是我当前使用的代码:
import { Server } from 'socket.io';
import redisAdapter from 'socket.io-redis';
import redis from 'redis';
const pubClient = redis.createClient({ host: REDIS_HOST, port: REDIS_PORT });
const subClient = pubClient.duplicate();
const adapter = redisAdapter(pubClient, subClient);
let io = null;
const WebSocketsManager = {
init: (server) => {
io = new Server(server, {
origins: '*:*',
path: '/public/socket.io',
});
io.adapter(adapter);
io.on('connection', (socket) => {
socket.on('disconnect', () => {
// Just logging it
});
socket.on('enteredRoomName', async (data) => {
const roomName = WebSocketsManager.getRoomName(data, 'RoomName');
socket.join(roomName);
const room = io.sockets.adapter.rooms.get(roomName);
console.log(`User ${socket.id} has joined the room '${roomName}' (total users in this room: ${room.size})`)
});
socket.on('exitedRoomName', async (data) => {
const roomName = WebSocketsManager.getRoomName(data, 'RoomName');
WebSocketsManager.exitRoom(roomName, socket);
});
});
},
getRoomName: (data, actionType) => {
// Some logic to create room name
},
exitRoom: (roomName, socket) => {
socket.leave(roomName);
const room = io.sockets.adapter.rooms.get(roomName);
console.log(`User ${socket.id} has left the room '${roomName}' (total users in this room: ${room.size})`)
},
};
我尝试过的另一件事是确保我有连接并且可以写入 Redis。
我尝试将此代码添加到“enteredRoomName”回调函数中:
await pubClient.set('mykey2', 'myvalue', (err, reply) => {
if (err) {
console.error(err);
} else {
console.log('Key saved successfully in Redis!');
}
});
实际上看到什么也没有发生,我收到了“客户端已关闭”的错误。
但是如果我使用 ioredis 包来连接(
pubClient = new Redis();
),我会在 redis 中获得新密钥。
但是如果我在
redisAdapter
中使用它作为参数,redis 中仍然没有任何内容。
好吧,我想我明白了,感谢这个帖子: socket.io 与 redis 存储
我应该在本地主机上启动我的应用程序的两个实例,以正确测试它。 完成此操作后,我可以使用 redis-cli 中的命令
MONITOR
来查看 Redis 中的 SET 和 Get。
希望它对某人有帮助。
附注另外,我必须添加
pubClient.connect();
和subClient.connect();
,因为here提到过。尽管文档中提到不再需要它了。
谢谢你的分享..很好