NodeJS 中的 Pub/Sub 实现

发布于 2024-11-05 05:20:23 字数 361 浏览 5 评论 0原文

我一直在研究 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

再浓的妆也掩不了殇 2024-11-12 05:20:24

为了对象持久化,我添加了Redis
支持使用node_redis。然后我
替换了 client.send 循环
使用 Redis pub/sub 的通道数组
作为一个抽象层。但我
注意到我需要创建一个新的
每个创建的用户的 Redis 客户端
订阅。我仍然需要
将socket.io客户端信息存储到
发送消息到发布。如何
是可扩展的吗?还有其他的吗
(更好)实施或进一步
我可以做哪些优化?什么会
你知道吗?

是的,你必须为每个 io 请求创建一个新的 redis 客户端。它很重并且不可扩展。但创建新的redis客户端连接并不会消耗太多内存。所以如果你的系统用户数不超过5000那就可以了。为了扩展,您可以添加从属 Redis 服务器来解决繁重的发布和订阅问题,如果您担心创建大量连接,那么您可以增加操作系统 uLIMIT。

您不需要在发送的消息中存储 socket.io 客户端。一旦redis收到订阅的频道消息。它将向特定的 io 客户端发送消息。

subscribe.on("message",function(channel,message) { 
 var msg = { message: [client.sessionId, message] }; 
 buffer.push(msg);
 if (buffer.length 15) buffer.shift(); 
 client.send(msg); > });

订阅多频道。我建议您预先存储所有具有多个频道的用户(您可以使用存储Mongodb或redis)。

var store = redis.createClient();
var subscriber= redis.createClient()

store.hgetall(UID, function(e, obj){
     subscriber.subscribe(obj.ChannelArray.toArray());
 })

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?

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.

subscribe.on("message",function(channel,message) { 
 var msg = { message: [client.sessionId, message] }; 
 buffer.push(msg);
 if (buffer.length 15) buffer.shift(); 
 client.send(msg); > });

To subscribe multi channel. I suggest you to pre-store all user with more than one channel(You can use storage Mongodb or redis).

var store = redis.createClient();
var subscriber= redis.createClient()

store.hgetall(UID, function(e, obj){
     subscriber.subscribe(obj.ChannelArray.toArray());
 })
眉黛浅 2024-11-12 05:20:24

我使用 Faye.js。说实话,这是我能找到的最简单的发布/订阅实现。也许这会有所帮助!

I use Faye.js. Seriously the simplest pub/sub implementation I could find. Maybe this will help!

孤檠 2024-11-12 05:20:24

尝试查看这个有关redis pub/的问题sub 和 socket.io。

Try to look at this question regarding redis pub/sub and socket.io.

尽揽少女心 2024-11-12 05:20:24

或者你可以尝试一下主宰。它使用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

泡沫很甜 2024-11-12 05:20:24

仅供参考 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文