2016-03-02 48 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應用的其他實例關閉,問題就會自行解決。