feat: heartbeat/rtt

This commit is contained in:
cha0s 2024-08-07 14:29:05 -05:00
parent 2dec51008d
commit d0644858af
4 changed files with 49 additions and 12 deletions

View File

@ -1,8 +1,9 @@
import {CLIENT_LATENCY} from '@/util/constants.js';
import {CLIENT_LATENCY, CLIENT_PREDICTION} from '@/util/constants.js';
import EventEmitter from '@/util/event-emitter.js';
export default class Client {
emitter = new EventEmitter();
rtt = 0;
throughput = {$$down: 0, down: 0, $$up: 0, up: 0};
constructor() {
setInterval(() => {
@ -13,6 +14,11 @@ export default class Client {
}, 250);
}
accept(packet) {
if ('Heartbeat' === packet.type) {
this.rtt = packet.payload.rtt;
this.send(packet);
return;
}
this.emitter.invoke(packet.type, packet.payload);
}
addPacketListener(type, listener) {
@ -22,7 +28,7 @@ export default class Client {
this.emitter.removeListener(type, listener);
}
send(packet) {
if (CLIENT_LATENCY > 0) {
if (CLIENT_LATENCY > 0 && !CLIENT_PREDICTION) {
setTimeout(() => {
this.transmit(packet);
}, CLIENT_LATENCY);

View File

@ -0,0 +1,3 @@
import Packet from '@/net/packet.js';
export default class Heartbeat extends Packet {}

View File

@ -34,8 +34,9 @@ export default function Devtools({
<div className={styles.dashboard}>
<form>
<div className={styles.engineBar}>
<div>{Math.round(((client.throughput.down * 8) / 1024) * 10) / 10}kb/s</div>
<div>{Math.round(((client.throughput.up * 8) / 1024) * 10) / 10}kb/s</div>
<div>{Math.round(client.rtt * 100) / 100}rtt</div>
<div>{Math.round(((client.throughput.down * 8) / 1024) * 10) / 10}kb/s down</div>
<div>{Math.round(((client.throughput.up * 8) / 1024) * 10) / 10}kb/s up</div>
</div>
</form>
<pre><code><small>{mainEntityJson}</small></code></pre>

View File

@ -117,6 +117,24 @@ export default class Engine {
}
this.incomingActions.get(connection).push(payload);
});
this.server.addPacketListener('Heartbeat', (connection) => {
const playerData = this.connectedPlayers.get(connection);
const {distance} = playerData;
const now = performance.now();
distance.rtt = (now - distance.last) / 1000;
playerData.heartbeat = setTimeout(() => {
distance.last = performance.now();
this.server.send(
connection,
{
type: 'Heartbeat',
payload: {
rtt: distance.rtt,
},
},
);
}, 1000);
});
}
acceptActions() {
@ -239,18 +257,26 @@ export default class Engine {
}
const ecs = this.ecses[entityJson.Ecs.path];
const entity = ecs.get(await ecs.create(entityJson));
entity.Player.id = id
this.connectedPlayers.set(
connection,
{
entity.Player.id = id;
const playerData = {
distance: {last: performance.now(), rtt: 0},
entity,
id,
memory: {
chunks: new Map(),
nearby: new Set(),
},
};
this.server.send(
connection,
{
type: 'Heartbeat',
payload: {
rtt: 0,
},
},
);
this.connectedPlayers.set(connection, playerData);
}
createEcs() {
@ -264,7 +290,8 @@ export default class Engine {
}
this.connectedPlayers.delete(connection);
this.incomingActions.delete(connection);
const {entity, id} = connectedPlayer;
const {entity, heartbeat, id} = connectedPlayer;
clearTimeout(heartbeat);
const json = entity.toJSON();
const ecs = this.ecses[entity.Ecs.path];
return Promise.all([