7

Socket.io API能够所有客户端发送消息。

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

如果我让客户端a连接到服务器y,客户端b连接到服务器z(以及用于存储的 Redis 盒)并且我socket.broadcast.emit在一台服务器上执行此操作,则另一台服务器上的客户端将收到此消息。如何?

实际连接到另一台服务器的客户端如何获得该消息?

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

2 回答 2

12

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 服务器雷迪斯。

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

于 2013-07-09T08:53:21.863 回答
1

有几种方法可以做到这一点。这个问题的更多信息。Redis 的 docs 中很好地解释了 Redis 中的 pub/sub 是如何工作的。在 Wikipedia 上,这里对范式的一般工作原理进行了解释。

引用 Redis 文档:

SUBSCRIBE、UNSUBSCRIBE 和 PUBLISH 实现了 Publish/Subscribe 消息传递范式,其中(引用 Wikipedia)发送者(发布者)没有被编程为将他们的消息发送给特定的接收者(订阅者)。相反,发布的消息被表征为通道,而不知道可能有什么(如果有的话)订阅者。订阅者表达对一个或多个频道的兴趣,并且只接收感兴趣的消息,而不知道有什么(如果有的话)发布者。发布者和订阅者的这种解耦可以实现更大的可扩展性和更动态的网络拓扑。

于 2013-07-02T20:13:21.313 回答