*Add heartbeat support to protocol
This commit is contained in:
parent
c67bc2bba7
commit
8ecd021a1d
|
@ -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 {
|
||||||
|
|
64
src/index.ts
64
src/index.ts
|
@ -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),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
Loading…
Reference in New Issue