概述
在一些需要频繁跟服务器进行数据交换的场景,比如游戏服务器。假设一个玩家每秒要向服务器发送30次数据包,如果玩家站着不动,那么这一秒发送的30个数据包都是完全相同的数据,这样造成了大量的性能和宽带的浪费,针对这种情况,服务器会使用数据缓存技术来减少服务器和客户端之间的数据传输量。
开始
实现的方法主要就是通过:
- 在客户端缓存玩家的状态,当状态不变时,停止向服务器发送数据包,从而避免发送重复的数据。
- 在服务器端,通过缓存一些常用数据,每次给玩家发送新的数据包的时候对比这些数据是否发生改变,避免每次向玩家发送重复的数据,以减少发送数据包的大小,从而减少宽带占用。
但同时还要考虑到玩家丢包的情况,比如某位玩家在移动的时候发生了丢包,过了一秒后他的网络恢复正常,但是因为该名玩家少接收了30个包,实际获得的数据并非完整的数据,此时他的人物动画仍然是"跑步"的状态,但是他本人早已停止了移动,就出现了玩家没有移动,但是人物的动画却一直在原地"跑步"。
为了消除这样的影响,推荐每隔5秒就给所有玩家发送一次游戏完整的数 据包,这样可以保证网络传输宽带最大化的利用的同时不造成过多的性能浪费。
diff 算法
在这里我们使用 jsondiffpatch
库来进行数据比对,jsondiffpatch
库是一个将两个 json 文档、文本、数组等进行对比,并生成diff、patch信息的 javascript 库,该库支持多种formatter格式输出。
安装:
npm install jsondiffpatch -S
使用方法:
const jsondiffpatch = require("jsondiffpatch");
let original = [
{
id: "1",
status: "idle",
x: 0,
y: 0,
},
{
id: "2",
status: "idle",
x: 100,
y: 100,
},
];
let modified = [
{
id: "1",
status: "run",
x: 999,
y: 0,
},
{
id: "2",
status: "idle",
x: 100,
y: 100,
},
];
function diffForArray(original, modified) {
return modified.map((el) => {
const data = original.find((o) => o.id === el.id);
if (data) {
const diff = jsondiffpatch.diff(data, el);
if (diff) {
return {
id: el.id,
...jsondiffpatch.patch({}, diff),
};
} else {
return {
id: el.id,
};
}
} else {
return el;
}
});
}
console.log(diffForArray(original, modified)); //[{ id: "1", status: "run", x: 999 }, { id: "2" }];