NodeJS/SocketIO 消息未可靠传送

NodeJS/SocketIO messages not being delivered reliably

我在 NodeJS/SocketIO 开发中遇到了非常奇怪的行为,我只是不知道是什么导致了我的问题。我几乎已经在我们的代码中尽可能地查看了所有地方,但找不到任何明显会导致此问题的内容。最后我让我们的一位网络人员建议它可能与 NodeJS 服务器上的负载平衡有关。我不确定这是否属实,但我想我会告诉您 guys/girls 这个问题,看看您是否有任何建议。

我们 运行 一个 NodeJS/SocketIO 应用程序,基本上允许我们基于 Web 的管理应用程序监控我们网站上用户的连接。实际上,它应该做的就是接收传入的消息并重新格式化消息,然后实时将它们重新广播给所有收听的客户端(这是我们所有基于 Web 的管理员的客户端)。本质上它是这样工作的...

我的问题是,当我 运行 一个 IP 上的一台 PC 上的基于 Web 的管理员实例,然后 运行 另一台 PC 上的同一基于 Web 的管理员的另一个实例和不同的IP - 同时 - 他们大多看不到相同的流量。在几乎所有情况下,来自用户的连接都会显示在一个或其他基于 Web 的管理实例中,但极少数情况下,连接会像我预期的那样出现在两者中。似乎来自 NodeJS/SocketIO 的几乎所有消息都被其中一个基于 Web 的管理员接收到,而另一个却没有收到,即使他们应该都在收听和接收相同的消息。我设计了代码,以便当 NodeJS/SocketIO 收到连接时,它会向所有正在侦听的客户端广播新的连接消息,其中应包括基于 Web 的管理员和基于 Web 的管理员实例都应看到所有传入连接和更新他们的观点以匹配。但是,这不会发生。这些消息几乎总是由基于 Web 的管理员实例之一而不是另一个实例接收。

但奇怪的是,当我 运行 2 个基于 Web 的管理员实例位于 2 台不同的 PC 但在同一 IP 上时,消息在两个基于 Web 的管理员中都被正确接收和处理。正如我所期望的那样,如果两个基于 Web 的管理员都运行使用不同的 IP。

我们的网络人员建议这可能与 NodeJS 服务器上的负载平衡有关。他建议,也许当基于 Web 的管理实例连接到 NodeJS 服务器时,它只能看到 NodeJS 服务器的一个实例,因此无法看到可能进入 NodeJS 服务器的另一个实例的所有连接。

服务器上的 NodeJS/SocketIO 应用程序 运行ning 看起来像这样...

var app = require('express')();

var http = require('http').Server(app);

var io = require('socket.io')(http);

http.listen(process.env.PORT, function(){
  console.log('listening on PORT:' + process.env.PORT);
});

io.on('connection', function(socket){

// Report a new connection and where it came from
var client_ip_address = socket.handshake.headers['x-forwarded-for'] ||    socket.request.socket.remoteAddress;
console.log("Connection from:" + client_ip_address);

socket.on('disconnect', function () {
    emitMessageToAll({type: "disconnect", ip: client_ip_address, senderID: socket.id});
});

// After a new user connects, we wait for them to emit to us the website they are currently on before notifying all users (Admin)
// Of the new connection. That way Admin can filter users by what site & page they are currently on. 
socket.on('newConnectionInfo',function(data){   
    console.log("User reports connection data: " + data.IP);    
    emitMessageToAll({type: "newConnection", ip: data.IP, url: data.url, senderID: socket.id});
});

socket.on('newBooking',function(data){  
    console.log("User reports new booking: " + data.IP);    
    emitMessageToAll({type: "newBooking", ip: data.IP,PurchDate: data.PurchDate, Surname: data.Surname});
});
});

function emitMessageToAll(data){
    io.emit('message',data);
    console.log("Sending:");
    console.log(data);
} 

无论如何,我完全不知道是什么导致了这个问题,你能提出任何可能导致这种非常奇怪的行为的想法吗?是否可能是负载平衡问题或服务器相关问题?

因此,在我的案例中,答案是服务器的负载平衡允许我们 NodeJS/SocketIO 应用程序的多个实例到 运行。我们同时有多达 3 个实例 运行ning,这导致一些连接通过实例 1 进行路由,一些通过实例 2 进行路由,另一些通过实例 3 进行路由。一旦 NodeJS/SocketIO 应用程序的其他实例关闭,问题自行解决。