2016-03-02 59 views
0

我在使用NodeJS/SocketIO开发时遇到了非常奇怪的行为,我只是不知道是什么导致了我的问题。我在我们的代码中几乎可以找到任何地方,但无法找到任何明显会导致此问题的东西。最后,我有一个网络家伙建议它可能与NodeJS服务器上的负载平衡有关。我不确定这是否属实,但我想我会告诉你们这些人/女孩这个问题,看看你们有没有什么建议。NodeJS/SocketIO消息未被可靠传送

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

  • 用户(通过我们的网站之一)连接到的NodeJS/SocketIO
    服务器和网站将消息发送到的NodeJS/SocketIO服务器 一个连接有发生。

  • NodeJS/SocketIO应用程序向控制台记录一条简短消息,告诉我们连接已建立。

  • 的的NodeJS/SocketIO应用程序,然后重新格式化消息并发射
    消息给所有连接。

  • 该消息包含NodeJS/SocketIO应用程序从用户ip接收到 连接的数据。

  • 基于Web的管理员然后收到该消息并更新它的视图 以显示所有当前连接的列表。

  • 当用户断开连接时,的NodeJS/SocketIO应用程序发送一个新的消息 的所有客户端的用户断开连接和基于web的
    管理员接收这些信息,然后更新了自己的看法。

我的问题是,当我在一个IP一个PC上运行的基于Web的管理的一个实例,然后另一台计算机和一个不同的IP上运行相同的基于Web的管理的另一个实例 - 在相同的两个时间 - 他们大多看不到相同的流量。在几乎所有情况下,来自用户的连接显示在一个或另一个基于Web的管理实例中,但很少,连接两者都出现,因为我也期望它。看起来几乎所有来自NodeJS/SocketIO的消息都是由基于Web的管理员之一接收的,而不是其他的,尽管他们都应该监听并接收相同的消息。我设计了代码,以便在NodeJS/SocketIO接收到连接时,它将新连接消息广播给所有正在监听的客户端,这些客户端应该包含基于Web的管理员,并且基于Web的管理员实例都应该看到所有传入连接并更新它们意见匹配。但是,这不会发生。这些消息几乎总是由基于Web的管理员实例之一接收,而不是其他实例。

奇怪的是,当我在两台不同的PC上运行2个基于Web的管理实例,但在同一个IP上时,这两个基于Web的管理员都能正确接收和处理消息。正如我所料,如果两个基于Web的管理员都在不同的IP上运行。

我们的网络人建议它可能与NodeJS服务器上的负载均衡有关。他建议,也许当一个基于Web的管理实例连接到NodeJS服务器时,它只能看到NodeJS服务器的一个实例,因此看不到NodeJS服务器的另一个实例中可能会出现的所有连接。

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

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); 
} 

无论如何,我在这里完全难倒什么可能导致该问题,可以认为,可能是任何想法造成这种奇怪的行为?它可能是一个负载平衡问题或服务器相关的问题?

回答

0

因此,在我的情况下,答案是服务器的负载平衡允许我们的NodeJS/SocketIO应用程序的多个实例运行。我们最多有3个并发运行的实例,这些实例导致一些连接通过实例1路由,一些通过实例2通过实例3通过实例2通路。一旦NodeJS/SocketIO应用的其他实例关闭,问题就会自行解决。