本帖最后由 (๑•ั็ω•็ั๑) 于 2023-7-25 11:44 编辑
一:原因
延迟问题:实时更新的全服排行榜需要实时更新服务器数据,但这可能会因为网络延迟而导致显示不准确。例如,玩家A的分数可能已经发生了变化,但因为网络延迟,其他玩家看到排行榜时可能还没有更新A的最新分数。这会导致其他玩家看到不准确的的信息,影响他们的体验。 服务器负载:实时更新的全服排行榜需要频繁地查询和更新服务器数据。这会增加服务器的负载,可能导致服务器过载或崩溃。 公平性问题:实时更新的全服排行榜可能会引发公平性问题。例如,如果玩家可以在排行榜更新时利用时间差或其他漏洞来获得不公平的优势,这会破坏游戏的公平性原则。
二:技术实现
https://forum.ark.online/forum.php?mod=viewthread&tid=1276 这里引用大佬的帖子说明一下KV服务器对存储的限制,这在我们在实际开发中也需要遵循相应的要求。在玩家请求存储数据之前,服务端检查当前是否可以set这个key如果可以,才set,具体的做法是可以添加一个canUpdate标签,每次set数据之后将canUpdate置为false,然后延迟一定时间间隔将其设置true,每次set操作判断当前标签。核心的代码实现如下:
/** 更新数据 */
private updateData() {
if (this._isUpdate) return;
this._isUpdate = true;
DataStorage.asyncGetCustomData(GlobalRankPrefix + this._customKey + this.getTimeKey()).then((data: Info[]) => {
let isChanged = false;
if (data) {
data.forEach((info) => {
const index = this._cacheData.findIndex((item) => item.userID === info.userID);
if (index === -1) {
this._cacheData.push(info);
} else if (this._cacheData[index].score < info.score) {
this._cacheData[index] = info;
}
});
this._cacheData.sort((a, b) => b.score - a.score);
if (this._cacheData.length > MaxRankItemViewLength) {
this._cacheData.length = MaxRankItemViewLength;
}
const UndefinedIndex = this._cacheData.findIndex(info => !info.userID);
if (UndefinedIndex != -1) {
this._cacheData.splice(UndefinedIndex, 1);
}
if (JSON.stringify(data) !== JSON.stringify(this._cacheData)) {
isChanged = true;
}
}
// 没有数据就初始化默认的假数据
else {
isChanged = true;
// 初始化默认数据
this.initDefaultData();
}
this._dataReplicated = JSON.stringify(this._cacheData);
if (isChanged) {
DataStorage.asyncSetCustomData(GlobalRankPrefix + this._customKey + this.getTimeKey(), this._cacheData);
}
});
setTimeout(() => {
this._isUpdate = false;
}, RankDataSaveTime);
}
其中的RankDataRaveTime就是指多久更新可以set数据的时间,是自定义的常量,一般大于6秒。
|