我每30秒打一次游戏服务器,并得到以下响应:
{
name: 'test',
map: 'pool',
maxplayers: 12,
players:
[ { deaths: 0,
kills: '0',
ping: 50,
name: 'test',
score: 0
} ],
}
我如何console.log这样的内容:“ $ {name}加入了服务器!”然后将上次调用中的数组更改为此,例如:
players:
[ { deaths: 0,
kills: '0',
ping: 50,
name: 'test',
score: 0
},
{ deaths: 0,
kills: '0',
ping: 20,
name: 'test2',
score: 0
}
]
我当时在考虑使用数据库并保存对它的响应,然后与最近一次调用中的新数组进行比较,但是我认为应该有一个更好的方法。
编辑:
我没有解释自己的正确性,我使用“ gamedig” npm模块从战场游戏服务器获取统计信息,我无权访问实际的服务器,我所知道的只是ip。
答案 0 :(得分:2)
有很多方法可以解决此问题,但是作为一个起点,我建议不要每30秒轮询一次服务器,如果可能的话,建议不要迁移到基于事件的系统。轮询本质上不是邪恶的,也不是任何东西,但它可能会长期导致扩展问题,并引起代码维护难题,例如您正在描述的问题。
首先,如果要确保客户端在游戏过程中不会突然失败,则肯定需要某种数据库来存储游戏状态。否则,导致服务器端代码重新启动的任何错误或崩溃将清除游戏状态,并且您不走运。您可以从以下任意一种中进行选择,但首先要看一下Redis或Firebase之类的内容,具体取决于您希望拥有的服务器类型。
第二,您可以更轻松地重建未接来电,例如,如果您既发出事件(例如,使用socket.io),则可以让客户端知道全局游戏状态何时更改,还可以将这些事件存储在时间同步的日志中。这样,如果客户端未在一定时间内收到更新(正是由于这个原因,某些游戏会从服务器保持心跳),它可以显式询问服务器错过了什么,并获得一系列事件自上次已知更新以来发生。最后一点意味着您发送的每条消息都包含一个时间戳,表示何时该消息良好运行,因此您可以忽略上次更新之前发生的事情。唯一事件ID对于跟踪已处理或未处理的事件也非常有用。
编辑
好吧,鉴于您没有服务器端可以使用,因此您在选择上确实受到限制。我认为最好的办法就是转换数据,以便您可以更轻松地检测到更改,例如基于用户名的哈希:
const users = {
'user1': { deaths: 0, kills: 0, score: 0 }
'user2': { deaths: 1, kills: 5, score: 3000 }
}
然后,在服务器发出的每个响应中,您只需要检查数组中每个用户的存在:
// serverUsers is whatever collection of users you get back in your poll
const newUsers = serverUsers.filter(u => Object.keys(users).includes(u.name));
很明显,检测玩家是否下线是相似的,只是方向相反,您会看到谁在“用户”集合中,而不在“ serverUsers”集合中。