NodeJS 中的 Pub/Sub 实现
我一直在研究 NodeJS 的不同发布/订阅实现,并且想知道哪一个最适合特定应用程序。该应用程序的要求涉及多通道、多用户 3D 环境中对象的实时同步。
我开始使用 socket.io,创建了一个基本的通道数组,当用户发送消息时,它会循环该通道中的用户并向用户的客户端发送消息。这很有效,我没有遇到任何问题。
对于对象持久化,我使用node_redis添加了Redis支持。然后我用 Redis pub/sub 作为抽象层替换了通道数组上的 client.send 循环。但我注意到我需要为每个订阅的用户创建一个新的 Redis 客户端。而且我仍然需要存储 socket.io 客户端信息以在发布时发送消息。其可扩展性如何?我可以做其他(更好的)实现或进一步优化吗?你会怎么办?
I've been playing around with different publish/subscribe implementations for nodeJS and was wondering which one would be best for a specific application. The requirements of the application involve real-time syncing of objects in multi-channel, multi-user 3D environments.
I started off using socket.io, created a basic array of channels, and when users send messages, it loops through the users in that channel and sends a message to the users' client. This worked well, and I had no problems with it.
For object persistence, I added Redis support using node_redis. Then I replaced the client.send loop on the array of channels with Redis pub/sub as a layer of abstraction. But I noticed that I needed to create a new Redis client for each user that made a subscription. And I still needed to store socket.io client information to send messages to on publish. How scalable is that? Are there other (better) implementations or further optimizations I could make? What would you do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
是的,你必须为每个 io 请求创建一个新的 redis 客户端。它很重并且不可扩展。但创建新的redis客户端连接并不会消耗太多内存。所以如果你的系统用户数不超过5000那就可以了。为了扩展,您可以添加从属 Redis 服务器来解决繁重的发布和订阅问题,如果您担心创建大量连接,那么您可以增加操作系统 uLIMIT。
您不需要在发送的消息中存储 socket.io 客户端。一旦redis收到订阅的频道消息。它将向特定的 io 客户端发送消息。
订阅多频道。我建议您预先存储所有具有多个频道的用户(您可以使用存储Mongodb或redis)。
Yes, you have to create a new redis client for every io request. It is heavy and not scalable. But creating a new redis client connection does not consume much memory. So if your system user count is not more than 5000 then it is ok. To scale you can add in slave redis server to resolve the heavy publish and subscribe and if you are concerned about creating a lot of connections then you can increase your OS uLIMIT.
You don't need to store socket.io client in message sent. Once redis received subscribed channel message. It will send message to particular io client.
To subscribe multi channel. I suggest you to pre-store all user with more than one channel(You can use storage Mongodb or redis).
我使用 Faye.js。说实话,这是我能找到的最简单的发布/订阅实现。也许这会有所帮助!
I use Faye.js. Seriously the simplest pub/sub implementation I could find. Maybe this will help!
尝试查看这个有关redis pub/的问题sub 和 socket.io。
Try to look at this question regarding redis pub/sub and socket.io.
或者你可以尝试一下主宰。它使用socket.io + redis pub sub中间件+node.js。支持所有传输。它帮助您处理客户端和redis之间的所有频道订阅或发布。 Juggernaut 是可扩展的,但只关心 redis 的开销,并且不支持身份验证(您可以对其进行一些处理)。然而,redis 每秒可以写入/读取 >150 k,因此对于您的情况来说应该没有问题。
https://github.com/maccman/juggernaut
Or you can try juggernaut. It using socket.io + redis pub sub middleware + node.js. Support all transports. It help you handler all channel subscribe or publish between client and redis. Juggernaut is scalable but only concern on overhead on redis and it not support authentication (you can do some trick on it). However redis can write/read >150 k per seconds so should be no problem for your case.
https://github.com/maccman/juggernaut
仅供参考 Socket.io v0.7 将支持通道,并且应该简化您现有的代码(不再有 pub/sub 库依赖项)
请参阅:http: //cl.ly/0B0C3f133K1m3j422n0K
FYI Socket.io v0.7 will support channels and should simplify your existing code (no more pub/sub lib dependencies)
See: http://cl.ly/0B0C3f133K1m3j422n0K