Node.js集群模块似乎打破了Socket.io握手

时间:2015-02-26 16:57:11

标签: node.js websocket socket.io fork

我有以下简单的WebSocket服务器围绕Socket.io库构建:

var PROCESSES = 1,
    cluster   = require('cluster'),
    i;

if (cluster.isMaster) {
    for (i = 0; i < PROCESSES; i++) {
        console.log('Forking worker', i);
        cluster.fork();
    }
} else {
    (function () {
        var server = require('http').Server(),
            io     = require('socket.io')(server);

        io.on('connection', function (socket) {
            socket.on('message', function (message) {
                socket.emit('message', message + ' too!');
            });
        });

        server.listen(8080);
    })();
}

启动时,它会创建一个服务器进程,该进程侦听WebSocket连接并将消息的变体回送给客户端:

$ iocat --socketio ws://localhost:8080
> i am hungry
i am hungry too!
> i like you
i like you too!
>

现在,当我将PROCESSES变量更改为大于1的数字时,客户端将无法再连接。

var PROCESSES = 2,
    ...

......导致......

$ iocat --socketio ws://localhost:8080
> client.on error
$ iocat -v --socketio ws://localhost:8080
> SIOClient> SIOClient: url-> ws://localhost:8080
SIOClient> onError { [Error: xhr poll error] description: 400 }
client.on error

我的直觉是,当给定多个工作进程时,群集模块不恰当地从一个进程切换到另一个进程中握手。但是我会想到整个连接,从发起握手的客户端到最后一端的套接字关闭,发生在一个持久的,保持活跃的连接上。

那到底是怎么回事?它怎么能解决?我熟悉使用Redis商店在不同机器上的服务器进程之间共享状态的想法,但这感觉就像我的用例过多的基础结构(从客户端收集事件流并回复确认)

版本:socket.io @ 1.3.3,node @ 0.10.36,在OS X 10.10和CentOS 6.6上看到

1 个答案:

答案 0 :(得分:1)

socket.io不是WebSockets上的简单包装器,它可以做得更多。打开握手是一个http请求,用于决定协议(WebSocket,轮询,闪存套接字等),在您的情况下,可能是WebSocket请求。如果那些进入不同的进程,握手将失败。

socket.io要求您使用粘性会话,以确保给定的客户端每次都能访问相同的进程。如果您想使用群集,他们建议您使用sticky-session module