*Add heartbeat support to protocol

This commit is contained in:
Derrick Hammer 2022-12-05 06:59:46 -05:00
parent c67bc2bba7
commit 8ecd021a1d
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
3 changed files with 67 additions and 4 deletions

View File

@ -7,6 +7,7 @@ enum Type {
DISCONNECTED = 4; DISCONNECTED = 4;
ADD_ITEM = 5; ADD_ITEM = 5;
REMOVE_ITEM = 6; REMOVE_ITEM = 6;
HEARTBEAT = 7;
} }
message Message { message Message {

View File

@ -56,7 +56,7 @@ export default class DHTCache extends EventEmitter {
this.flood.on("message", (message, id) => this.onGetBroadcast(message, id)); this.flood.on("message", (message, id) => this.onGetBroadcast(message, id));
this.swarm.on("connection", (peer: any) => this.swarm.on("connection", (peer: any) =>
this.flood.send(peer, b4a.from("hello"), 0) this.send(peer, b4a.from("hello"))
); );
[...this.swarm.peers.values()] [...this.swarm.peers.values()]
@ -69,6 +69,8 @@ export default class DHTCache extends EventEmitter {
}); });
this._ensurePeer(this.id); this._ensurePeer(this.id);
setInterval(() => this._heartbeatCheck(), 5 * 1000);
setInterval(() => this._emitHeartbeat(), 60 * 1000);
} }
private _cache: Set<string>; private _cache: Set<string>;
@ -163,8 +165,8 @@ export default class DHTCache extends EventEmitter {
this.flood.broadcast(message, ttl); this.flood.broadcast(message, ttl);
} }
public send(message: any) { public send(peer: any, message: any) {
this.flood.send(message, 0); this.flood.send(peer, message, 0);
} }
protected addPeerHandler(peer: any) { protected addPeerHandler(peer: any) {
@ -186,6 +188,8 @@ export default class DHTCache extends EventEmitter {
id, id,
}); });
this._emitHeartbeat(peer);
if (this.bootstrapped) { if (this.bootstrapped) {
return; return;
} }
@ -278,6 +282,15 @@ export default class DHTCache extends EventEmitter {
} else if (type === Type.BOOTSTRAP_RESPONSE) { } else if (type === Type.BOOTSTRAP_RESPONSE) {
const { bootstrap } = decoded; const { bootstrap } = decoded;
this._bootstrapFrom(bootstrap); this._bootstrapFrom(bootstrap);
} else if (type === Type.HEARTBEAT) {
let { id: toId, signature, data: bufData } = decoded;
toId = b4a.from(toId as Uint8Array);
if (signature && crypto.verify(bufData, signature, id)) {
this._addEntityConnection(id, toId as Buffer);
this._setEntity(toId as Buffer, { heartbeat: Date.now() });
}
} }
} }
@ -447,4 +460,49 @@ export default class DHTCache extends EventEmitter {
} }
})(); })();
} }
private _heartbeatCheck() {
for (const peer of this.connectedTo) {
const pubkey = b4a.from(peer, "hex");
const heartbeat = this.graph.node.get(peer)?.heartbeat;
const conn = this.swarm._allConnections.get(pubkey);
if (!conn) {
this.onRemovePeer({ remotePublicKey: pubkey });
continue;
}
if (heartbeat > 0 && Date.now() - heartbeat > 60 * 1000) {
conn.end();
}
}
}
private _emitHeartbeat(peer?: any) {
let peers = [...this.connectedTo];
if (peer) {
// @ts-ignore
peers = [b4a.from(peer.remotePublicKey).toString("hex")];
}
for (const peer of peers) {
const pubkey = b4a.from(peer, "hex");
const conn = this.swarm._allConnections.get(pubkey);
if (!conn) {
continue;
}
const data = b4a.from(Uint8Array.from([1]));
this.send(
conn,
this._compileMessage({
type: Type.HEARTBEAT,
id: this.id,
data,
signature: crypto.sign(data, this.swarm.keyPair.secretKey),
})
);
}
}
} }

View File

@ -78,7 +78,11 @@ export enum Type {
/** /**
* @generated from protobuf enum value: REMOVE_ITEM = 6; * @generated from protobuf enum value: REMOVE_ITEM = 6;
*/ */
REMOVE_ITEM = 6 REMOVE_ITEM = 6,
/**
* @generated from protobuf enum value: HEARTBEAT = 7;
*/
HEARTBEAT = 7
} }
// @generated message type with reflection information, may provide speed optimized methods // @generated message type with reflection information, may provide speed optimized methods
class Message$Type extends MessageType<Message> { class Message$Type extends MessageType<Message> {