3

Socket IO 服务器在 NodeJs 的单个实例上运行良好。但是,当我使用 NodeJS 的集群模块在多个内核上运行服务器时,我收到错误消息,“在收到握手响应之前连接已关闭”。我google了一下原因,发现

问题的本质是,当你在一个服务器上运行多个Node应用线程(worker),或者多个服务器时,socket.io客户端连接被集群以随机循环的方式路由,并且握手/授权的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);
    }
};

我还尝试按照文档中的建议使用适配器 for redis。

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

4

0 回答 0