Socket.io'Handhake'因集群和粘性会话而失败

时间:2015-02-13 21:15:40

标签: node.js session websocket socket.io cluster-computing

即使是一个简单的例子,我也无法使粘性会话socket.io模块正常工作。按照自述文件(https://github.com/indutny/sticky-session)中给出的非常小的例子,我只是想让这个例子起作用:

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')
});

和一个简单的客户:

var socket = require('socket.io-client')('http://localhost:3001');

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

工人们很好。 http服务器工作正常。但是当客户端连接时,控制台会记录“有人联系”,仅此而已。客户端永远不会触发on connect事件,所以我认为升级/握手失败或者其他什么。如果有人能够发现我做错了什么会有所帮助。

谢谢!

2 个答案:

答案 0 :(得分:3)

@jordyyy:谷歌搜索后我遇到了同样的问题我得到了很好的回答。 Socket.Io握手任务在多个请求中完成,当您在粘性会话上运行时,这意味着您根据自己的核心使用多个流程。

因此握手请求将分配到不同的进程上,并且无法通话。(不是IPC)(它们是子进程),大多数时间连接都将失败/丢失。(连接断开事件)经常发生)

那么什么是解决方案?解决方案是socketio-sticky-session

Socketio-sticky-session,基于IP管理连接。因此,当您将要求任何客户端进行请求时,它将维护与进程/工作者相关的IP地址。因此,进一步的请求将转发给同一个流程/工作人员,并确保您的连接稳定。

当您使用redies适配器时,您实际上可以维护套接字 连接数据b / w所有进程/工作人员。

了解更多信息 https://github.com/elad/node-cluster-socket.io  (如果你的服务器支持IPv6,你需要在worker_index方法上有一些补丁)

只是知识字节。 :):)

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

答案 1 :(得分:0)

这是超级旧的,当我需要它时没有真正回答,但我的解决方案是放弃这个坏模块和任何其他超级混乱的模块,只需使用pub / sub与redis适配器。唯一的另一个步骤是强制传输到websockets,如果这困扰任何人,那么使用其他东西。出于我的目的,我的解决方案简单易读,并没有弄乱'典型'socket.io api,最重要的是它工作得非常好。