我有以下简单的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上看到
答案 0 :(得分:1)
socket.io
不是WebSockets上的简单包装器,它可以做得更多。打开握手是一个http请求,用于决定协议(WebSocket,轮询,闪存套接字等),在您的情况下,可能是WebSocket请求。如果那些进入不同的进程,握手将失败。
socket.io
要求您使用粘性会话,以确保给定的客户端每次都能访问相同的进程。如果您想使用群集,他们建议您使用sticky-session module。