2012-07-01 99 views
1

我使用node.js進行遊戲配對(例如,多個客戶端連接服務器,如果有多個玩家,則彼此連接;或者他們將被踢出30秒)。如何在使用Node.js進行遊戲配對時進行設計

目前,我使用套接字連接(這可以檢測到意外丟失的連接)。但我不能配對想出一個優雅的方式:

var net = require('net'); 
var _clients = new Array(); 

net.createServer(function(_socket) { 
    _socket.on('data', function(_data) { 
    //Parse client data 
    _clients.push(_socket); 
    setTimeout(function(){ 
     _socket.write('kicked\n'); 
    },30*1000); 
    _socket.on('close', function(data) { 
    //Delete _socket from _clients 
    } 
}).listen(6969, '127.0.0.1'); 

setInterval(function(){ 
    var pair = new Array(); 
    while(_clients.length>2) 
    { 
    var _s1 = _clients.pop(), _s2 = _clients.pop(); 
    // Pair _s1 & _s2 
    } 
},2*1000); 

目前的代碼工作,但它是非常糟糕的設計:(

(1)setInterval的使用,而不是異步調用(2)維護一個類似_clients的數組是不方便的,因爲我必須處理「踢」/丟失的連接/對或其他情況。

PS。目前我按時間順序配對客戶端,但可能是隨機對或其他條件是需要避免在線玩家總是與同樣的人配對。

回答

2

爲什麼不使用類似以下的東西?

沒有連接池

var net = require('net') 
, pendingPair = null; 

net.createServer(function(_socket) { 
    _socket.on('data', function(_data) { 
    //Parse client data 
    if(!pendingPair) { 
     pendingPair = _socket; 
    } else { 
     // Now you have a pair! 
     var p1 = pendingPair 
     , p2 = _socket; 

     pendingPair = null; 
    } 
}).listen(6969, '127.0.0.1'); 

你只要連接時,系統就會自動對。你仍然需要在某處追蹤這些套接字來踢客戶端,並且斷開連接,但是你應該能夠擺脫setIntervals。

隨着連接池

var net = require('net') 
    , _ = require('underscore')._ 
    , clients = {} 
    , games = {}; 

function setKickTimer(socket) { 
    socket.kickTimer = setTimeout(function() { 
     socket.write('kicked\n'); 
    }, 30 * 1000); 
} 

net.createServer(function(socket) { 
    socket.id = Math.floor(Math.random() * 1000); 
    setKickTimer(socket); 
    clients[socket.id] = socket; 

    socket.on('data', function(data) { 
     socket.data = parseData(data); 
    } 

    socket.on('close', function(data) { 
     var opponent = _.find(clients, function(client) { return client.opponentId === socket.id; }); 
     // The opponent is no longer part of a pair. 
     if(opponent) { 
      delete opponent.opponentId; 
      setKickTimer(opponent); 
     } 

     delete clients[socket.id]; 
    } 

}).listen(6969, '127.0.0.1'); 

setInterval(function(){ 
    // Get the client ids of clients who are not matched, and randomize the order 
    var unmatchedClientIds = _.shuffle(_.keys(_.filter(clients, function(client) { return !client.opponentId; }))); 
    while(unmatchedClientIds > 2) { 
     var c1 = unmatchedClientIds.pop(), 
      , c2 = unmatchedClientIds.pop(); 

     clearTimeout(clients[c1].kickTimer); 
     clearTimeout(clients[c2].kickTimer); 
     clients[c1].opponentId = c2; 
     clients[c2].opponentId = c1; 
    } 
},2*1000); 

這不是一個完整的工作解決方案,但它應該給你如何管理從隊列中掉線,踢用戶的想法。注意我正在使用underscore.js使集合上的操作更容易。

+0

非常感謝。這確實有助於消除時間間隔,但如果我想保留連接池並將它們有條件地配對(不配對最近的兩個),它不起作用。 – Kanglai

+0

您可以做一個或另一個。如果你想要一個連接池和連接順序更隨機的配對,你可能需要間隔地做些事情。這並不一定有什麼問題。 –

+0

非常感謝。我只是想避免setIntervals ... – Kanglai

相關問題