gpt4 book ai didi

javascript - 使用集群将 Socket.IO 扩展到多个 Node.js 进程时的一些问题

转载 作者:太空宇宙 更新时间:2023-11-04 03:05:14 25 4
gpt4 key购买 nike

我的 Node.js 服务器使用集群模块来处理多个进程。

如果服务器通过Socket.IO接收到来自客户端的请求,它会通过redis发布将数据传送到另一台服务器。它通过 redis 订阅接收精炼的数据,然后将这些数据扔给客户端。

我使用一个 Node 进程通过redis sub接收数据,其他进程通过socket.io向客户端发送数据。

当页面加载时,客户端连接socket.io。在这里,这是我的问题。连接事件反复发生,甚至页面未加载。当客户端连接时,我从该套接字获取 socket.id,稍后当我想向该客户端套接字发送数据时使用它。但是这个连接反复发生,我认为客户端使用的套接字发生了变化。所以,我记住的第一个socket.id将毫无用处。我无法从该 socket.id 发送数据。我将身份验证信息存储在套接字对象中,因此更改客户端套接字没有帮助。

索引.pug

    $(document).ready(function(){
var socket = io.connect();
(...)

app.js

    var cluster = require('cluster');
var socketio = require('socket.io');
var NRP = require('node-redis-pubsub');
var nrpForChat = new NRP(config.chatRedisConfig);
var nrpForCluster = new NRP(config.clusterRedisConfig);



var startExpressServer = function(){
var app = express();
var server = require('http').createServer(app);
var io = socketio.listen(server);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6380 }));


io.sockets.on('connection', function(socket){
socketController.onConnect(io, socket, nrpForChat);
});


server.listen(config.port, function(){
console.log('Server app listening on port '+config.port);
});


nrpForCluster.on('to:others:proc', function(data){
var socket = io.sockets.connected[data.target.sockid];
if (socket) {
if (data.event == '_net_auth') {
if (data.data.res){
socket.enterId = data.data.data.enterId;
socket.memberKey = data.data.data.memberKey;
socket.sid = data.data.data.sid;
socket.emit(data.event, data.data);
}else{
console.log('auth failed.');
}
}
} else {
socket.emit(data.event, data.data);
}
});

module.exports = app;
}


var numCpus = require('os').cpus().length;

if (cluster.isMaster) {
for (var i = 0; i < numCpus; i++) {
cluster.fork();
}
}
else {
if (cluster.worker.id == numCpus) {

nrpForChat.on('chat:to:relay', function(data){
nrpForCluster.emit('to:others:proc', data);
});

if (numCpus == 1) {
startExpressServer();
}
}
else {
startExpressServer();
}
}

最佳答案

默认情况下,socket.io 连接多个连续的 http 请求。它本质上以 HTTP 轮询模式启动,然后在一些初始数据交换后,切换到 webSocket 传输。

因此,没有任何粘性负载平衡的集群将无法工作。每个最初的连续 http 请求都应该发送到同一服务器进程,但可能会被发送到集群中的不同服务器进程,并且初始连接将不起作用。

据我所知有两种解决方案:

  1. 实现某种粘性负载平衡(在集群模块中),以便每个客户端重复访问同一个服务器进程,因此连接开始时的所有连续 http 请求都将访问同一个服务器进程。

  2. 切换您的客户端配置以立即切换到 webSocket 传输,并且永远不要使用 HTTP 轮询。连接仍将以 http 请求启动(因为所有 webSocket 连接都是这样启动的),但完全相同的连接将升级为 webSocket,因此只会有一个连接。

仅供引用,您还需要确保 socket.io 中的重新连接逻辑正确地重新连接到所连接的原始服务器进程。

socket.io 将 Node.js 集群支持与 Redis 结合使用。虽然 socket.io 文档网站已经关闭多天了,但您可以找到一些信息 hereScaling Socket.IO to multiple Node.js processes using cluster这是 previously cached version of the socket.io doc for clustering .

关于javascript - 使用集群将 Socket.IO 扩展到多个 Node.js 进程时的一些问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42715006/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com