Node.js Socket.io';握手';群集和粘性会话失败
即使是一个简单的例子,我也无法让sticky sessions socket.io模块正常工作。按照自述文件()中给出的非常简单的示例,我只是想让这个示例起作用:Node.js Socket.io';握手';群集和粘性会话失败,node.js,session,websocket,socket.io,cluster-computing,Node.js,Session,Websocket,Socket.io,Cluster Computing,即使是一个简单的例子,我也无法让sticky sessions socket.io模块正常工作。按照自述文件()中给出的非常简单的示例,我只是想让这个示例起作用: var cluster = require('cluster'); var sticky = require('sticky-session'); var http = require('http'); if (cluster.isMaster) { for (var i = 0; i < 4; i++) {
var cluster = require('cluster');
var sticky = require('sticky-session');
var http = require('http');
if (cluster.isMaster) {
for (var i = 0; i < 4; i++) {
cluster.fork();
}
Object.keys(cluster.workers).forEach(function(id) {
console.log("Worker running with ID : " +
cluster.workers[id].process.pid);
});
}
if (cluster.isWorker) {
var anotherServer = http.createServer(function(req, res) {
res.end('hello world!');
});
anotherServer.listen(3000);
console.log('http server on 3000');
}
sticky(function() {
var io = require('socket.io')();
var server = http.createServer(function(req, res) {
res.end('socket.io');
});
io.listen(server);
io.on('connection', function onConnect(socket) {
console.log('someone connected.');
socket.on('sync', sync);
socket.on('send', send);
function sync(id) {
socket.join(id);
console.log('someone joined ' + id);
}
function send(id, msg) {
io.sockets.in(id).emit(msg);
console.log('someone sent ' + msg + ' to ' + id);
}
});
return server;
}).listen(3001, function() {
console.log('socket.io server on 3001')
});
工人们开始干得很好。http服务器工作正常。但是,当客户端连接时,控制台会记录“有人连接”,仅此而已。客户端从未触发on connect事件,因此我认为升级/握手失败或是其他什么。如果有人能发现我做错了什么,那会有很大帮助
谢谢 @jordyy:在谷歌搜索之后,我也面临着同样的问题,我有一个很好的答案。 Socket.Io握手任务在多个请求中完成,当您在粘性会话上运行时,这意味着您正在根据您的核心使用多个进程。 因此,握手请求将分布在不同的进程上,它们不能交谈。(不是IPC)(它们是子进程),并且大部分时间连接将失败/丢失。(连接断开事件频繁发生) 那么什么是解决方案呢?解决办法是 Socketio sticky会话,基于IP管理连接。所以,当任何客户端请求时,它都会维护进程/工作者的ip地址。因此,进一步的请求将转发给同一流程/工作人员,并且您的连接将正确稳定 当您使用redies适配器时,您就可以实际维护套接字了 连接数据b/w所有流程/工人 更多信息 (如果您的服务器支持IPv6,则需要对worker_索引方法进行修补) 仅限知识字节:)
还有一件事,您不需要分叉过程。它将通过粘性会话完成 这是一个非常古老的问题,当我需要它时,它并没有得到真正的回答,但我的解决方案是删除这个糟糕的模块和任何其他超级混乱的模块,只使用带有redis适配器的pub/sub。唯一的另一个步骤是强制传输到WebSocket,如果这让任何人感到困扰,那么就使用其他方法。出于我的目的,我的解决方案简单易读,没有弄乱“典型”socket.io api,最重要的是它工作得非常好。解决过这个问题吗?我只是遇到了客户端不断重新连接的问题,根本没有维护本质上的粘性会话。我不想使用redis,因为我希望一切都简单,但最终我不得不这么做。redis适配器非常易于使用,您无需进行任何配置。只需安装redis并将所有内容连接起来。为了在集群上工作,我必须做最后一件事:我必须在客户端和服务器上指定传输:web套接字。WS必须是第一个(WS,然后是轮询)或唯一选项。做了这两件事之后,一切都很完美。如果需要的话,我可以用例子更新我的答案。谢谢你的回复,是的,那将非常有帮助:)谢谢你的输入。我很乐意接受建议,但问题是关于一个特定的模块,我真的不认为使用另一个模块是一个好方法answer@jordyyy:欢迎:)当您打开此模块库时。这只是一个单文件脚本。与您所写的相同,除了连接处理:)将传输限制为仅限于websocket对我很有效。您能为我们这些想要尝试您的解决方案的人添加代码吗?
var socket = require('socket.io-client')('http://localhost:3001');
socket.on('connect', function() {
console.log('connected')
socket.emit('sync', 'secret')
});