Node.js Socket.io';握手';群集和粘性会话失败

Node.js Socket.io';握手';群集和粘性会话失败,node.js,session,websocket,socket.io,cluster-computing,Node.js,Session,Websocket,Socket.io,Cluster Computing,即使是一个简单的例子,我也无法让sticky sessions socket.io模块正常工作。按照自述文件()中给出的非常简单的示例,我只是想让这个示例起作用: var cluster = require('cluster'); var sticky = require('sticky-session'); var http = require('http'); if (cluster.isMaster) { for (var i = 0; i < 4; i++) {

即使是一个简单的例子,我也无法让sticky sessions socket.io模块正常工作。按照自述文件()中给出的非常简单的示例,我只是想让这个示例起作用:

var cluster = require('cluster');
var sticky = require('sticky-session');
var http   = require('http');

if (cluster.isMaster) {
  for (var i = 0; i < 4; i++) {
    cluster.fork();
  }

  Object.keys(cluster.workers).forEach(function(id) {
    console.log("Worker running with ID : " + 
      cluster.workers[id].process.pid);
  });
}

if (cluster.isWorker) {
  var anotherServer = http.createServer(function(req, res) {
    res.end('hello world!');
  });
  anotherServer.listen(3000);
  console.log('http server on 3000');
}

sticky(function() {
  var io = require('socket.io')();

  var server = http.createServer(function(req, res) {
    res.end('socket.io');
  });

  io.listen(server);

  io.on('connection', function onConnect(socket) {
    console.log('someone connected.');

    socket.on('sync', sync);
    socket.on('send', send);

    function sync(id) {
      socket.join(id);
      console.log('someone joined ' + id);
    }

    function send(id, msg) {
      io.sockets.in(id).emit(msg);
      console.log('someone sent ' + msg + ' to ' + id);
    }
  });

  return server;
}).listen(3001, function() {
  console.log('socket.io server on 3001')
});
工人们开始干得很好。http服务器工作正常。但是,当客户端连接时,控制台会记录“有人连接”,仅此而已。客户端从未触发on connect事件,因此我认为升级/握手失败或是其他什么。如果有人能发现我做错了什么,那会有很大帮助


谢谢

@jordyy:在谷歌搜索之后,我也面临着同样的问题,我有一个很好的答案。 Socket.Io握手任务在多个请求中完成,当您在粘性会话上运行时,这意味着您正在根据您的核心使用多个进程。

因此,握手请求将分布在不同的进程上,它们不能交谈。(不是IPC)(它们是子进程),并且大部分时间连接将失败/丢失。(连接断开事件频繁发生)

那么什么是解决方案呢?解决办法是

Socketio sticky会话,基于IP管理连接。所以,当任何客户端请求时,它都会维护进程/工作者的ip地址。因此,进一步的请求将转发给同一流程/工作人员,并且您的连接将正确稳定

当您使用redies适配器时,您就可以实际维护套接字了 连接数据b/w所有流程/工人

更多信息 (如果您的服务器支持IPv6,则需要对worker_索引方法进行修补)

仅限知识字节:)


还有一件事,您不需要分叉过程。它将通过粘性会话完成

这是一个非常古老的问题,当我需要它时,它并没有得到真正的回答,但我的解决方案是删除这个糟糕的模块和任何其他超级混乱的模块,只使用带有redis适配器的pub/sub。唯一的另一个步骤是强制传输到WebSocket,如果这让任何人感到困扰,那么就使用其他方法。出于我的目的,我的解决方案简单易读,没有弄乱“典型”socket.io api,最重要的是它工作得非常好。

解决过这个问题吗?我只是遇到了客户端不断重新连接的问题,根本没有维护本质上的粘性会话。我不想使用redis,因为我希望一切都简单,但最终我不得不这么做。redis适配器非常易于使用,您无需进行任何配置。只需安装redis并将所有内容连接起来。为了在集群上工作,我必须做最后一件事:我必须在客户端和服务器上指定传输:web套接字。WS必须是第一个(WS,然后是轮询)或唯一选项。做了这两件事之后,一切都很完美。如果需要的话,我可以用例子更新我的答案。谢谢你的回复,是的,那将非常有帮助:)谢谢你的输入。我很乐意接受建议,但问题是关于一个特定的模块,我真的不认为使用另一个模块是一个好方法answer@jordyyy:欢迎:)当您打开此模块库时。这只是一个单文件脚本。与您所写的相同,除了连接处理:)将传输限制为仅限于websocket对我很有效。您能为我们这些想要尝试您的解决方案的人添加代码吗?
var socket = require('socket.io-client')('http://localhost:3001');

socket.on('connect', function() { 
  console.log('connected')
  socket.emit('sync', 'secret') 
});