2013-04-10 26 views
0

想象一下web套接字服務器。當我收到連接時,我需要將該連接保存在它所屬的池中(將池視爲「同級」的「空間」)。這是需要的,因爲我需要向同一個池中的對等點廣播內容。當代碼是 - 當然 - 所有異步,即使節點是單線程的,似乎維護一個全局數組是不可靠的(我不知道這是怎麼可能的,儘管...):在壓力測試,消息以非常快的速度流向服務器,我將連接保存在結構中,但通常下一條消息沒有找到更新的結構(仍然?),行爲不正常。如何在nodejs中可靠地維護一個連接的套接字數組?

應用程序使用Redis的,但插座不能序列...

通信基於WebSockets的,通過SockJS(我用Socket.io在以前的迭代)。

我確定這是一個衆所周知的已經解決的問題,但我仍然沒有看到光明:我在這裏錯過了什麼?

我的會話對象或多或少是這樣的(不僅僅是一個僞代碼......它比這更復雜)。

var Sessions = { 

    sockets: {}, 

    add: function(poolId, socket) { 
    sockets[poolId].push(socket); 
    }, 

    find: function(poolId) { 
    return sockets[poolId]; 
    }, 

    remove: function ... 

} 

回答

0

我不知道我明白你的確切問題是什麼,但這裏是維護一個套接字池的服務器的一個例子。一旦連接套接字可以發送消息,只有廣播到他們指定的池,這是我相信你正試圖完成。另外,當客戶端斷開連接時,它將從池中刪除它。

var net = require('net'); 
var util = require('util'); 

var currentPool = 1; 
var server = net.createServer(); 

//add a new socket to the assigned pool stored on the listening server instance 
server.addToPool = function(s){ 
    if(!server.connPools){ 
    server.connPools = {}; 
    } 

    if(!server.connPools[s.poolId]){ 
    server.connPools[s.poolId] = []; 
    } 

    server.connPools[s.poolId].push(s); 

    s.on('close', clientCloseHandler); 
    s.on('data', clientDataHandler); 

}; 

//broadcast data from client to other clients in their pool 
function clientDataHandler(data){ 

    for(var a=0; a < server.connPools[this.poolId].length; a++){ 
    server.connPools[this.poolId][a].write(data); 
    } 

} 

//remove client form pool on disconnect 
function clientCloseHandler(){ 
    var tmp = null; 
    for(var a=0; a < server.connPools[this.poolId].length; a++){ 
    if(this.remotePort === a.remotePort){ 
     tmp = a; 
     break; 
    } 
    } 
    server.connPools[this.poolId].splice(tmp,1); 
} 

//add new client to pool 
function newClient(s){ 
    s.poolId = currentPool; 
    server.addToPool(s); 

    if(currentPool === 1){ 
    currentPool = 2; 
    }else{ 
    currentPool = 1 
    } 

} 

server.on('connection', newClient); 

server.listen(9999);