如何使用NodeJS的集群模块在多个核心上正确运行socketio服务器?

套接字IO服务器在单个NodeJs实例上运行良好。 但是,当我使用NodeJS的集群模块运行多核心服务器时,我收到错误,“连接closures之前收到一个握手响应”。 我find了原因,发现,

问题的实质是,当您在服务器或多个服务器上运行多个节点应用程序线程(worker)时,socket.io客户端连接将按照随机循环方式由群集路由,握手/授权的客户端请求将被移交到那些他们没有握手/授权的工人那里乱七八糟的地方开始。 来源链接

我已经尝试了一些东西,使其工作,但迄今没有成功。 这是代码

'use strict'; process.env.NODE_ENV = process.env.NODE_ENV || 'development'; var express = require('express'); var config = require('./config/environment'); var session = require('express-session'); var redisStore = require('connect-redis')(session); var cluster = require('cluster'); var domain = require('domain'); var socketIo = require('./config/socketio'); var REDIS = require('redis') var store = REDIS.createClient(); var pub = REDIS.createClient(); var sub = REDIS.createClient(); if(cluster.isMaster) { var numWorkers = require('os').cpus().length; for(var i = 0; i < numWorkers; i++) { cluster.fork(); } } else { var d = domain.create (); d.on ("error", function (error){ // start new server }); // Setup server var app = express(); var server = require('http'); d.run (function (){ server = server.createServer(app); }); require('./config/express')(app); require('./config/redis')(); require('./routes')(app); server.listen(config.port, config.ip, function () { console.log('Express server listening on %d, in %s mode', config.port, app.get('env')); }); var redis = require('socket.io-redis'); var socketIO = require('socket.io')(server, { serveClient: (config.env === 'production') ? false : true, path: '/socket.io-client' }); sub.subscribe('chat'); socketIO.adapter(redis( {host: 'localhost', port: 6379})); socketIo.createSocketConnection('/dummy', socketIO, sub, pub, store); exports = module.exports = app; } 

文件:./config/socketio

 'use strict'; function addNamespaceForId (socketio, namespace, sub, pub, store){ socketio.of(namespace).on('connection', function(socket) { onConnect(socketio, socket, namespace, sub, pub, store); console.info('[%s] CONNECTED', socket.address); sub.on('message', function(pattern, key){ store.hgetall(key, function(e, obj){ socket.send(obj.uid + ": " + obj.text) }) }) socket.on('disconnect', function() { console.info('[%s] DISCONNECTED', socket.address); }); }); } } function onConnect(io, socket, namespace, sub, pub, store) { socket.on('message', function(from, msg) { store.incr("messageNextId", function(e, id){ store.hmset("messages:" + id, { uid: socket.sessionId, text: 'text;' }, function(e, r){ pub.publish("chat", "messages:" + id) }) }) io.emit('broadcast', { payload : from['message'], source : from }); io.of(namespace).emit('broadcast', { payload : from['message'], source : from }); }); // When the client emits 'info', this listens and executes socket.on('info', function(data) { console.info('[%s] %s', socket.address, JSON.stringify(data, null, 2)); }); // Insert sockets below require('../api/thing/thing.socket').register(socket); } module.exports = { createSocketConnection : function (namespace, socketio, sub, pub, store){ addNamespaceForId(socketio, namespace, sub, pub, store); } }; 

我也尝试使用redis的适配器,如文档中所build议的。

这种设置有时可以但不总是。 我无法找出缺点。