我正在使用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。目前,我正在按时间顺序对客户进行配对,但是可能需要随机配对或其他条件来避免在在线玩家数量不多的情况下始终配对同一个人。
最佳答案
为什么不使用以下内容?
(无连接池)
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来简化对集合的操作。
关于sockets - 使用Node.js进行游戏配对时如何设计,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11281762/