2023-01-21 14:53:41 +00:00
|
|
|
const RingBuffer = require('./RingBuffer');
|
|
|
|
|
|
|
|
var NetworkDoctor = function(capacity) {
|
|
|
|
this.reset(capacity);
|
|
|
|
};
|
|
|
|
|
|
|
|
NetworkDoctor.prototype.reset = function(capacity) {
|
|
|
|
this.sendingQ = new RingBuffer(capacity);
|
|
|
|
this.inputFrameDownsyncQ = new RingBuffer(capacity);
|
|
|
|
this.peerInputFrameUpsyncQ = new RingBuffer(capacity);
|
|
|
|
this.peerInputFrameUpsyncCnt = 0;
|
|
|
|
this.immediateRollbackFrames = 0;
|
2023-01-22 03:34:02 +00:00
|
|
|
this.skippedRenderFrameCnt = 0;
|
|
|
|
|
|
|
|
this.inputRateThreshold = gopkgs.ConvertToNoDelayInputFrameId(60);
|
|
|
|
this.peerUpsyncThreshold = 8;
|
|
|
|
this.rollbackFramesThreshold = 8; // Roughly the same as TurnAroundFramesToRecover
|
2023-01-21 14:53:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
NetworkDoctor.prototype.logSending = function(stFrameId, edFrameId) {
|
|
|
|
this.sendingQ.put({
|
|
|
|
i: stFrameId,
|
|
|
|
j: edFrameId,
|
|
|
|
t: Date.now()
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
NetworkDoctor.prototype.logInputFrameDownsync = function(stFrameId, edFrameId) {
|
|
|
|
this.inputFrameDownsyncQ.put({
|
|
|
|
i: stFrameId,
|
|
|
|
j: edFrameId,
|
|
|
|
t: Date.now()
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
NetworkDoctor.prototype.logPeerInputFrameUpsync = function(stFrameId, edFrameId) {
|
|
|
|
const firstPopped = this.peerInputFrameUpsyncQ.put({
|
|
|
|
i: stFrameId,
|
|
|
|
j: edFrameId,
|
|
|
|
t: Date.now()
|
|
|
|
});
|
|
|
|
if (null != firstPopped) {
|
|
|
|
this.peerInputFrameUpsyncCnt -= (firstPopped.j - firstPopped.i + 1);
|
|
|
|
}
|
|
|
|
this.peerInputFrameUpsyncCnt += (edFrameId - stFrameId + 1);
|
|
|
|
};
|
|
|
|
|
2023-01-22 03:34:02 +00:00
|
|
|
NetworkDoctor.prototype.logRollbackFrames = function(x) {
|
|
|
|
this.immediateRollbackFrames = x;
|
2023-01-21 14:53:41 +00:00
|
|
|
};
|
|
|
|
|
2023-01-22 03:34:02 +00:00
|
|
|
NetworkDoctor.prototype.stats = function() {
|
|
|
|
let sendingFps = 0,
|
|
|
|
srvDownsyncFps = 0,
|
|
|
|
peerUpsyncFps = 0,
|
|
|
|
rollbackFrames = this.immediateRollbackFrames;
|
|
|
|
if (1 < this.sendingQ.cnt) {
|
|
|
|
const st = this.sendingQ.getByFrameId(this.sendingQ.stFrameId);
|
|
|
|
const ed = this.sendingQ.getByFrameId(this.sendingQ.edFrameId - 1);
|
|
|
|
const elapsedMillis = ed.t - st.t;
|
|
|
|
sendingFps = Math.round((ed.j - st.i) * 1000 / elapsedMillis);
|
|
|
|
}
|
|
|
|
if (1 < this.inputFrameDownsyncQ.cnt) {
|
|
|
|
const st = this.inputFrameDownsyncQ.getByFrameId(this.inputFrameDownsyncQ.stFrameId);
|
|
|
|
const ed = this.inputFrameDownsyncQ.getByFrameId(this.inputFrameDownsyncQ.edFrameId - 1);
|
|
|
|
const elapsedMillis = ed.t - st.t;
|
|
|
|
srvDownsyncFps = Math.round((ed.j - st.i) * 1000 / elapsedMillis);
|
|
|
|
}
|
|
|
|
if (1 < this.peerInputFrameUpsyncQ.cnt) {
|
|
|
|
const st = this.peerInputFrameUpsyncQ.getByFrameId(this.peerInputFrameUpsyncQ.stFrameId);
|
|
|
|
const ed = this.peerInputFrameUpsyncQ.getByFrameId(this.peerInputFrameUpsyncQ.edFrameId - 1);
|
|
|
|
const elapsedMillis = ed.t - st.t;
|
|
|
|
peerUpsyncFps = Math.round(this.peerInputFrameUpsyncCnt * 1000 / elapsedMillis);
|
|
|
|
}
|
|
|
|
return [sendingFps, srvDownsyncFps, peerUpsyncFps, rollbackFrames, this.skippedRenderFrameCnt];
|
2023-01-21 14:53:41 +00:00
|
|
|
};
|
|
|
|
|
2023-01-22 03:34:02 +00:00
|
|
|
NetworkDoctor.prototype.logSkippedRenderFrameCnt = function() {
|
|
|
|
this.skippedRenderFrameCnt += 1;
|
|
|
|
}
|
2023-01-21 14:53:41 +00:00
|
|
|
|
2023-01-22 03:34:02 +00:00
|
|
|
NetworkDoctor.prototype.isTooFast = function() {
|
|
|
|
const [sendingFps, srvDownsyncFps, peerUpsyncFps, rollbackFrames, skippedRenderFrameCnt] = this.stats();
|
|
|
|
if (sendingFps >= this.inputRateThreshold && srvDownsyncFps >= this.inputRateThreshold) {
|
|
|
|
// At least my network is OK for both TX & RX directions.
|
|
|
|
if (rollbackFrames >= this.rollbackFramesThreshold && peerUpsyncFps < this.peerUpsyncThreshold) {
|
|
|
|
// I got many frames rolled back while none of my peers effectively helped my preciction.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
2023-01-21 14:53:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = NetworkDoctor;
|