一个Node.js集群上的SocketIO

我有一个独立的Node.js应用程序,它具有侦听某个端口,例如8888的SocketIO服务器。现在我试图在一个集群中运行该应用程序,并且由于集群随机分配工作人员的请求,一旦握手,XHR轮询模式下的SocketIO客户端并授权与一名工人被路由到另一名工人,他们不握手,混乱开始。

而且由于员工不分享任何东西,我找不到解决方法。 有没有一个已知的解决这个问题?

没有“简单”的解决scheme。 你需要做的是以下几点:

  • 如果一个客户端连接到一个worker,那么在global(= for all workers accessible)store(即redis)中保存connection-id和worker-id以及一个潜在的附加标识-id。
  • 如果一个客户端被路由到另一个工作者,使用该商店来查找哪个工作者负责这个客户端(使用连接ID或附加的标识ID,然后交给该工作者(或者使用nodejs-工人 – 主 – 工 – 通信或通过redis-pub-sub)

我用sock.js实现了这样的事情,并且还有一些复杂性:我有两个node.js服务器,每个都有四个worker,所以我不得不使用redis-pub-sub进行工作/员工通信,因为不能保证他们在同一台机器上。

其实有一个简单的解决scheme :使用Redis来存储套接字状态。
一切都在Socket.IO文档中解释:

Socket.IO中的默认“会话”存储位于内存( MemoryStore )中。

MemoryStore只允许你在一个进程上部署socket.io 。 如果要扩展到多个进程和/或多个服务器,可以使用我们的RedisStore ,它使用Redis NoSQL数据库作为中间的人。

所以为了把商店实例RedisStore我们添加这个:

 var RedisStore = require('socket.io/lib/stores/redis') , redis = require('socket.io/node_modules/redis') , pub = redis.createClient() , sub = redis.createClient() , client = redis.createClient(); // Needs to be done after 'listen()' io.set('store', new RedisStore({ redisPub : pub , redisSub : sub , redisClient : client })); 

当然你需要运行一个redis服务器。