node.js - Socket.io 'Handshake' 因集群和粘性 session 而失败

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

即使是一个简单的示例,我也无法使粘性 session 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') 
});

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

谢谢!

最佳答案

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

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

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

Socketio-sticky-session,基于IP管理连接。因此,当您收到任何客户端请求时,它将维护尊重进程/工作人员的 IP 地址。因此,进一步的请求将转发给同一进程/工作人员,并且您的连接已正确稳定。

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

了解更多信息 https://github.com/elad/node-cluster-socket.io (如果您的服务器支持 IPv6,则需要对worker_index方法进行一些修补)

只是知识字节。 :) :)

还有一件事,你不需要 fork 进程。这将通过粘性 session 来完成。

关于node.js - Socket.io 'Handshake' 因集群和粘性 session 而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28508858/

相关文章:

javascript - 连接nodejs和云mqtt

php - 重定向不适用于 Header(Location) 和 session 变量

http - websocket 如何知道服务器已关闭?

spring - 通过浏览器关闭页面导致 Websocket 错误 : "An established connection was aborted by the software in your host machine"

javascript - 维护套接字监听器的标准方法

javascript - 如何在node.js中以异步方式多次(动态)调用一个方法

java - 使用编码算法在 RAM 中存储 4x4 2D 矩阵,以实现最小的 RAM 空间使用

javascript - 使用 Express 和 Socket.IO 的 session 支持的解释?

websocket - 是否可以将 socket.io 服务器与纯 html5 websockets 一起使用?

javascript - 使用下划线基于数组减少对象项