socket.io如何跨多个服务器发送消息?

时间:2013-07-02 17:07:45

标签: node.js websocket redis socket.io

Socket.io API可以向所有客户端发送消息。

在内存中有一台服务器和所有套接字,我理解该服务器如何向所有客户端发送消息,这很明显。但是使用Redis来存储套接字的多个服务器呢?

如果我将客户 a 连接到服务器 y ,客户 b 连接到服务器 z (和商店的Redis框)我在一台服务器上socket.broadcast.emit,另一台服务器上的客户端将收到此消息。怎么样?

实际连接的客户端如何获取该消息?

  • 是否有一台服务器告诉其他服务器向其连接的客户端发送消息?
  • 服务器是否与客户端建立了自己的连接以发送该消息?

2 个答案:

答案 0 :(得分:8)

Socket.io默认使用MemoryStore,因此所有连接的客户端都将存储在内存中,使得连接到不同socket.io服务器的客户端发送和接收事件变得不可能(好吧,不安静,但稍后会更多)

使所有socket.io服务器接收所有事件的一种方法是所有服务器都使用redis的pub-sub。因此,使用socket.emit可以发布到redis。

redis_client = require('redis').createClient();
redis_client.publish('channelName', data);

并且所有套接字服务器都通过redis订阅该频道,并在收到消息时将其发送给连接到它们的客户端。

redis_sub = require('redis').createClient();
redis_sub.subscribe('channelName', 'moreChannels');

redis_sub.on("message", function (channel, message) {        
    socket.emit(channel, message);
});

复杂的东西!!但是等等,结果你实际上并不需要这种代码来实现目标。 Socket.io有RedisStore,它基本上可以以更好的方式执行上面代码应该做的事情,这样你就可以像编写单个服务器那样编写Socket.io代码,并且仍然可以通过它传播到其他socket.io服务器redis的。

总结一下,socket.io通过使用redis作为通道而不是内存来跨多个服务器发送消息。

答案 1 :(得分:1)

有几种方法可以做到这一点。更多信息in this question。关于Redis中pub / sub如何工作的一个很好的解释是here, in Redis' docs。关于范式如何起作用的解释是here, on Wikipedia

引用Redis文档:

  

SUBSCRIBE,UNSUBSCRIBE和PUBLISH实现发布/订阅   消息传递范例(引用维基百科)发件人(出版商)   未编程将其消息发送给特定接收器   (用户)。相反,已发布的消息被表征为   频道,不知道可能有什么(如果有的话)用户。   订阅者表示对一个或多个频道感兴趣,并且仅接收   感兴趣的消息,不知道什么(如果有的话)   出版商有。这使发布者和订阅者脱钩   可以实现更高的可扩展性和更动态的网络拓扑。