1

ゲームのペアリングに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);

現在のコードは機能しますが、設計が本当に悪いです:(

(1)非同期呼び出しではなく、SetInterval が使用されます。(2) _clients のような配列を維持するのは不便です。なぜなら、「キック」/接続/ペアの切断やその他の状況に対処しなければならないからです。

PS。現在、私はクライアントを時系列でペアリングしていますが、オンライン プレイヤーがそれほど多くないときに常に同じ人をペアリングすることを避けるために、ランダム ペアまたはその他の条件が必要になる可能性があります。

4

1 に答える 1

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を使用していることに注意してください。

于 2012-07-04T10:14:48.190 に答える