Javascript nodeJS中的Pub/sub实现

Javascript nodeJS中的Pub/sub实现,javascript,node.js,redis,publish-subscribe,Javascript,Node.js,Redis,Publish Subscribe,我一直在研究nodeJS的不同发布/订阅实现,想知道哪种实现最适合于特定的应用程序。该应用程序的要求包括在多通道、多用户3D环境中实时同步对象 我从使用socket.io开始,创建了一个基本的通道数组,当用户发送消息时,它会循环该通道中的用户,并向用户的客户端发送消息。这很有效,我没有任何问题 对于对象持久性,我使用node_Redis添加了Redis支持。然后,我将通道数组上的client.send循环替换为Redis pub/sub作为抽象层。但我注意到,我需要为每个订阅的用户创建一个新的R

我一直在研究nodeJS的不同发布/订阅实现,想知道哪种实现最适合于特定的应用程序。该应用程序的要求包括在多通道、多用户3D环境中实时同步对象

我从使用socket.io开始,创建了一个基本的通道数组,当用户发送消息时,它会循环该通道中的用户,并向用户的客户端发送消息。这很有效,我没有任何问题

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

我用。说真的,这是我能找到的最简单的发布/订阅实现。也许这会有帮助

试着看看关于redis pub/sub和socket.io的问题

对于对象持久性,我添加了Redis 支持使用node_redis。然后我 已替换上的client.send循环 带有Redis发布/订阅的频道阵列 作为抽象层。但我 注意到我需要创建一个新的 每个用户的Redis客户端 订阅我仍然需要 将socket.io客户端信息存储到 发布时将消息发送到。怎么 那是什么?还有其他的吗 (更好)实施或进一步 我可以做的优化?你会怎么做 是吗

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

您不需要在message sent中存储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); > });
订阅多频道。我建议您使用多个通道预存储所有用户(您可以使用storage Mongodb或redis)


FYI Socket.io v0.7将支持通道,并应简化现有代码(不再依赖发布/订阅库)


请参阅:

或者您可以尝试juggernaut。它使用socket.io+redis发布子中间件+node.js。支援所有运输工具。它可以帮助您处理客户端和redis之间的所有通道订阅或发布。Juggernaut是可伸缩的,但只考虑redis的开销,不支持身份验证(您可以对其进行一些操作)。但是,redis每秒可以写入/读取大于150 k的数据,因此对于您的情况来说应该没有问题


这对单个频道效果很好,但对多个频道效果不是很好吗?也许如果您跟踪消息中的频道名称,并确认用户在消息上的频道中,但似乎冗余且低效。@Detect:它可能冗余且低效,但您仍然可以胜过其他解决方案,因为redis本机针对高级别并发连接进行了优化。找到答案的唯一方法是对每个解决方案进行基准测试。这看起来很有希望。我能看到的唯一缺点是支持的传输的数量。两个(WebSocket和轮询)vs socket.io的六个受支持的传输。这是很好的反馈。我会考虑这些建议。谢谢,这是一个进步。我担心如果不使用共享内存解决方案,将socket.io客户端信息保留在内存中将无法扩展。这就是为什么我要用Redis作为替代品。
var store = redis.createClient();
var subscriber= redis.createClient()

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