如何通过socket.io向多个服务器进程发送消息给各个客户端?

我即将从socket.io开始,这是一个理论上的问题,假设我想用socket.io发送一个消息给特定的用户,通常我必须存储与相关的userid的socketid,发送时,获取socketid并发送。

但是如果我有多个服务器进程运行? 我将不得不确保客户端实际连接的正确的服务器发送。 可能吗 ?

对于多个服务器实例,您需要有一个用于身份validation的caching服务(memcache,redis),以及一个中心消息队列服务(stormMQ,rabbitMQ,AQ,基于Java的mq),您的所有节点实例都将绑定到该服务。 因此,一个Node实例绑定到每个客户端/通道/消息队列,其他所有绑定的Node实例都会收到消息并转发给客户端。

问题通常是关于如何玩WebSocket集群:

  • 几个前端服务器将负责处理与每个客户端的双向连接。 他们形成WebSocket群集。
  • 几个后端服务器将负责处理您的应用程序的业务逻辑。

每次后端想要通知客户端,它都会向WebSocket集群发送一个请求,该集群有责任与客户端进行通信。 一种可能的情况:

  • 用唯一的ID标识每个WebSocket群集的服务器。
  • 使用唯一的ID识别每个客户端。
  • 每次客户端连接一个WebSocket集群的服务器时,将其唯一的ID和服务器的唯一ID一起存储在一个分布式的键/值(如数据库)中。
  • 这样你就知道哪个客户端与哪个服务器连接了。
  • 下一次您的后端应用程序想要通知客户端有两种可能性:
    1. 该对(clientId,serverId)不在数据库中,您不能通知客户端。
    2. 这个对(clientId,serverId)出现在数据库中,那么你必须要求serverId标识的服务器通知clientId标识的客户端。

笔记:

  • 每个WebSocket集群的服务器都可以运行一个node.js实例,通过socket.io进行超级充电。 它必须提供一个将clientId作为参数的路由,并使用socket.io来通知这个客户端。 事实上,socket.io知道客户端正在使用该服务器上的哪个套接字。
  • 每次你的服务器崩溃,你必须清理你的数据库,并删除所有包含服务器ID的对。
  • 部署一个WebSocket集群可能很乏味,所以你有Kaazing这样的商业产品。
  • 一个好的分布式密钥/值像数据库是Riak 。 出于上述目的,它比Redis或Memcached要好,因为它可以很容易地分布在数据中心和多个数据中心。