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

时间:2016-03-20 11:02:36

标签: node.js redis socket.io node-redis node-cluster

Socket IO服务器在单个NodeJ实例上运行正常。但是,当我使用NodeJS的集群模块在多个核心上运行服务器时,我收到错误," Connection在收到握手响应之前关闭了#34;。我用Google搜索了原因并发现了,

  

问题的实质是,当您在服务器或多个服务器上运行多个节点应用程序线程(工作程序)时,socket.io客户端连接由群集以随机循环方式路由,并且握手/授权io客户端请求交给工人,他们没有动手/授权,混乱开始。 Source Link

我已经尝试了几项让它发挥作用但到目前为止没有成功。这是代码

'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 / stuffetio

'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,如documentation.

中所述

此设置有时有效,但并非总是如此。我无法弄清楚缺失点。

0 个答案:

没有答案