群集节点应用程序时,Socket.io websocket授权失败 [英] Socket.io websocket authorization failing when clustering node application
问题描述
我已经构建了一个使用Express和Socket.io的应用程序,它基于Node.js构建。我想合并群集以增加我的应用程序可以处理的请求数量。
I've built an application which uses Express and Socket.io, built on Node.js. I'd like to incorporate clustering to increase the amount of requests that my application can process.
以下原因导致我的应用程序产生套接字握手错误。 。
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('death', function(worker) {
console.log('worker ' + worker.pid + ' died');
});
} else {
app.listen(3000);
}
控制台日志显示socket.io正在启动多个时间。
jack@jack:~$ node nimble/app.js
info - socket.io started
info - socket.io started
info - socket.io started
info - socket.io started
info - socket.io started
info - socket.io started
info - socket.io started
info - socket.io started
info - socket.io started
Socket.io目前正在我的服务器代码顶部设置:
var io = require('socket.io').listen(app);
websocket授权码:
//Auth the user
io.set('authorization', function (data, accept) {
// check if there's a cookie header
if (data.headers.cookie) {
data.cookie = parseCookie(data.headers.cookie);
data.sessionID = data.cookie['express.sid'];
//Save the session store to the data object
data.sessionStore = sessionStore;
sessionStore.get(data.sessionID, function(err, session){
if(err) throw err;
if(!session)
{
console.error("Error whilst authorizing websocket handshake");
accept('Error', false);
}
else
{
console.log("AUTH USERNAME: " + session.username);
if(session.username){
data.session = new Session(data, session);
accept(null, true);
}else {
accept('Invalid User', false);
}
}
})
} else {
console.error("No cookie was found whilst authorizing websocket handshake");
return accept('No cookie transmitted.', false);
}
});
错误消息的控制台日志:
Error whilst authorizing websocket handshake
debug - authorized
warn - handshake error Error
推荐答案
您的 sessionStore
是什么?如果是连接
附带的 MemoryStore
,则不会在您的工作人员之间共享会话。每个工作人员都有自己的会话集,如果客户端连接到另一个工作人员,您将找不到他们的会话。我建议你看看,例如 connect-redis 用于在进程之间共享会话。基本用法:
What is your sessionStore
? If it's the MemoryStore
shipped with connect
, then sessions won't be shared between your workers. Each worker will have it's own set of sessions, and if a client connects to another worker, you wont find their session. I suggest you take a look at e.g. connect-redis for sharing sessions between processes. Basic usage:
var connect = require('connect')
, RedisStore = require('connect-redis')(connect);
var app = connect.createServer();
app.use(connect.session({store: new RedisStore, secret: 'top secret'});
当然,这要求你也设置redis。在 Connect wiki 有CouchDB,memcached,postgres等模块。
Of course, this requires that you also set up redis. Over at the Connect wiki there are modules for CouchDB, memcached, postgres and others.
这只能解决部分问题,因为现在你在工人之间分享了会话,但是 socket.io
无法向连接到其他工作人员的客户端发送消息。基本上,如果您发出 socket.emit
在一个worker中,该消息只会被发送给连接到同一个worker的客户端。一个解决方案是使用 RedisStore
for socket .io
,它利用redis在工人之间路由消息。基本用法:
This only solves part of your problem, though, because now you have sessions shared between workers, but socket.io
has no way of sending messages to clients which are connected to other workers. Basically, if you issue a socket.emit
in one worker, that message will only be sent to clients connected to that same worker. One solution to this is to use RedisStore
for socket.io
, which leverages redis to route messages between workers. Basic usage:
var sio = require('socket.io')
, RedisStore = sio.RedisStore
, io = sio.listen(app);
io.set('store', new RedisStore);
现在,无论连接到哪个工作人员,所有消息都应路由到客户端。
Now, all messages should be routed to clients no matter what worker they are connected to.
这篇关于群集节点应用程序时,Socket.io websocket授权失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!