我正在使用 PM2 在集群模式下设置 socket.io。
我正在使用socket.io-redis
包,它在集群模式下工作正常。
但是当我想访问所有连接的套接字时,问题就出现了。因为进程不知道集群模式下其他进程中的套接字连接。
我认为socket.io-redis
跟踪所有连接的套接字及其所有会话信息,但事实并非如此。是否有任何方法或解决方案可以访问 socket.io/Nodejs 中所有进程中存在的所有套接字连接?
我正在使用 PM2 在集群模式下设置 socket.io。
我正在使用socket.io-redis
包,它在集群模式下工作正常。
但是当我想访问所有连接的套接字时,问题就出现了。因为进程不知道集群模式下其他进程中的套接字连接。
我认为socket.io-redis
跟踪所有连接的套接字及其所有会话信息,但事实并非如此。是否有任何方法或解决方案可以访问 socket.io/Nodejs 中所有进程中存在的所有套接字连接?
Socket.io-redis 确实在某种意义上保持跟踪..
从他们的文档
“Redis 适配器扩展了内存适配器的广播功能:数据包也被发布到 Redis 通道(通道名称格式见下文)。
每个 Socket.IO 服务器都会接收到这个数据包并将其广播到自己的已连接套接字列表中。”
所以基本上,redis 被用作代理来告诉每个套接字服务器基于 X 通道等发出。允许您在集群模式下使用 socket.io 服务器,但是正如您所提到的,当您需要保留它时它可能会不足跟踪发射之外的事物。
那么这会给我们带来什么影响呢.. 好吧,您可以通过 socket.io-redis 使用自定义钩子,但我个人发现它真的很难理解和使用,并且个人成功有限。我认为使用新版本的 socket.io 和 socket.io redis 进行了一些调整以使其更简单,但是我没有尝试过。
相反,我们所做的是使用 redis hset 和 jget 来存储套接字和用户的 ID,然后当我们想要让所有用户在线时,我们可以查询 redis 以获取在线用户列表或特定房间中的用户等。
您要做的是添加 redis 包并连接到常规的 pub/sub。
然后,当用户为此加入房间或您的服务器时,您将执行 hset。在第一次加入时,我们的看起来像这样
redis.hset([collection-name],[Field],[value])
所以在代码中它看起来像
redis.hset(decoded.cID,"socket-" + socket.id,socket.nickname)
这将在 redis 中设置一个值,因此集合名称是一个值(对我们来说它是频道的唯一 id),然后我们为字段存储“socket.id”以及该值的“昵称”。此值是用户 ID 或匿名(如果他们未登录)
然后,当我们想抓取房间里的人时,我们使用 hget 命令
redis.HGETALL([collection-name],function(err,results){}
所以在说emit的内部,我们调用redis.HGETALL命令来获取我们传入的特定集合中的所有项目并将其发送回所有连接的用户。