2

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

而且因为工人不分享任何东西,我找不到解决方法。这个问题有已知的解决方案吗?

4

2 回答 2

1

没有“简单”的解决方案。您需要做的是:

  • 如果客户端连接到工作人员,请将连接 ID 与工作人员 ID 和潜在的附加标识 ID 一起保存在全局(=所有工作人员可访问的)存储(即 redis)中。
  • 如果客户端被路由到另一个工作人员,请使用存储查找哪个工作人员对该客户端负责(使用连接 ID 或附加标识 ID,然后将其交给该工作人员(使用 nodejs- worker-master-worker-communication 或通过 redis-pub-sub)

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

于 2013-06-04T08:40:07.097 回答
1

实际上有一个简单的解决方案:使用Redis存储套接字状态。Socket.IO 文档
中解释了一切:

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

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

因此,为了将store实例更改为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 服务器。

于 2013-07-24T10:37:32.677 回答