如何devise使用Node.js进行游戏配对

我使用node.js进行游戏配对(例如,多个客户端连接服务器,如果有多个玩家连接,或者连续踢30秒)。

目前,我使用套接字连接(这可以检测到意外丢失的连接)。 但我无法弄清楚配对的优雅方式:

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

目前的代码工作,但它确实糟糕的devise:(

(1)使用SetInterval,而不是asynchronous调用。 (2)保持像_clients这样的数组是不方便的,因为我必须处理“踢”/丢失的连接/对或其他情况。

PS。 目前我按时间顺序来配对客户,但也许随机配对或其他条件,以避免在线玩家不是那么多时总是配对相同的人。

为什么不使用类似以下的东西?

没有连接池

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

一旦build立连接,您就可以获得自动配对。 你仍然需要跟踪那些sockets来踢客户端,并且断开连接,但是你应该能够摆脱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); 

这不是一个完整的工作解决scheme,但它应该给你一个如何pipe理丢弃的连接和从队列踢用户的想法。 注意我正在使用underscore.js使集合上的操作更容易。