mirror of
https://github.com/pezkuwichain/pezkuwi-telemetry.git
synced 2026-05-31 04:41:06 +00:00
Add ping to the client, reconnect on dead connections
This commit is contained in:
@@ -93,21 +93,28 @@ export default class Feed {
|
|||||||
return {
|
return {
|
||||||
action: Actions.RemovedChain,
|
action: Actions.RemovedChain,
|
||||||
payload: label
|
payload: label
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static subscribedTo(label: Types.ChainLabel): FeedMessage.Message {
|
public static subscribedTo(label: Types.ChainLabel): FeedMessage.Message {
|
||||||
return {
|
return {
|
||||||
action: Actions.SubscribedTo,
|
action: Actions.SubscribedTo,
|
||||||
payload: label,
|
payload: label
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsubscribedFrom(label: Types.ChainLabel): FeedMessage.Message {
|
public static unsubscribedFrom(label: Types.ChainLabel): FeedMessage.Message {
|
||||||
return {
|
return {
|
||||||
action: Actions.UnsubscribedFrom,
|
action: Actions.UnsubscribedFrom,
|
||||||
payload: label,
|
payload: label
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static pong(payload: string): FeedMessage.Message {
|
||||||
|
return {
|
||||||
|
action: Actions.Pong,
|
||||||
|
payload
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendData(data: FeedMessage.Data) {
|
public sendData(data: FeedMessage.Data) {
|
||||||
@@ -131,15 +138,28 @@ export default class Feed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private handleCommand(cmd: string) {
|
private handleCommand(cmd: string) {
|
||||||
if (cmd.startsWith('subscribe:')) {
|
const [tag, payload] = cmd.split(':', 2) as [string, Maybe<string>];
|
||||||
|
|
||||||
|
if (!payload) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tag) {
|
||||||
|
case 'subscribe':
|
||||||
if (this.chain) {
|
if (this.chain) {
|
||||||
this.events.emit('unsubscribe', this.chain);
|
this.events.emit('unsubscribe', this.chain);
|
||||||
this.chain = null;
|
this.chain = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const label = cmd.substr(10) as Types.ChainLabel;
|
this.events.emit('subscribe', payload as Types.ChainLabel);
|
||||||
|
break;
|
||||||
|
|
||||||
this.events.emit('subscribe', label);
|
case 'ping':
|
||||||
|
this.sendMessage(Feed.pong(payload));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.error('Unknown command tag:', tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export const Actions = {
|
|||||||
RemovedChain : 0x09 as 0x09,
|
RemovedChain : 0x09 as 0x09,
|
||||||
SubscribedTo : 0x0A as 0x0A,
|
SubscribedTo : 0x0A as 0x0A,
|
||||||
UnsubscribedFrom : 0x0B as 0x0B,
|
UnsubscribedFrom : 0x0B as 0x0B,
|
||||||
|
Pong : 0x0C as 0x0C,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Action = typeof Actions[keyof typeof Actions];
|
export type Action = typeof Actions[keyof typeof Actions];
|
||||||
@@ -98,6 +99,11 @@ export namespace Variants {
|
|||||||
action: typeof Actions.UnsubscribedFrom;
|
action: typeof Actions.UnsubscribedFrom;
|
||||||
payload: ChainLabel;
|
payload: ChainLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PongMessage extends MessageBase {
|
||||||
|
action: typeof Actions.Pong;
|
||||||
|
payload: string; // just echo whatever `ping` sent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Message =
|
export type Message =
|
||||||
@@ -112,7 +118,8 @@ export type Message =
|
|||||||
| Variants.AddedChainMessage
|
| Variants.AddedChainMessage
|
||||||
| Variants.RemovedChainMessage
|
| Variants.RemovedChainMessage
|
||||||
| Variants.SubscribedToMessage
|
| Variants.SubscribedToMessage
|
||||||
| Variants.UnsubscribedFromMessage;
|
| Variants.UnsubscribedFromMessage
|
||||||
|
| Variants.PongMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opaque data type to be sent to the feed. Passing through
|
* Opaque data type to be sent to the feed. Passing through
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ import * as FeedMessage from './feed';
|
|||||||
|
|
||||||
export { Types, FeedMessage };
|
export { Types, FeedMessage };
|
||||||
|
|
||||||
export const VERSION: Types.FeedVersion = 5 as Types.FeedVersion;
|
// Increment this if breaking changes were made to types in `feed.ts`
|
||||||
|
export const VERSION: Types.FeedVersion = 6 as Types.FeedVersion;
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ export class Connection {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private pingId = 0;
|
||||||
|
private pingTimeout: NodeJS.Timer;
|
||||||
|
private pingSent: Maybe<Types.Timestamp> = null;
|
||||||
private socket: WebSocket;
|
private socket: WebSocket;
|
||||||
private state: Readonly<State>;
|
private state: Readonly<State>;
|
||||||
private readonly update: Update;
|
private readonly update: Update;
|
||||||
@@ -72,6 +75,8 @@ export class Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bindSocket() {
|
private bindSocket() {
|
||||||
|
this.ping();
|
||||||
|
|
||||||
this.state = this.update({
|
this.state = this.update({
|
||||||
status: 'online',
|
status: 'online',
|
||||||
nodes: new Map()
|
nodes: new Map()
|
||||||
@@ -87,7 +92,42 @@ export class Connection {
|
|||||||
this.socket.addEventListener('error', this.handleDisconnect);
|
this.socket.addEventListener('error', this.handleDisconnect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ping = () => {
|
||||||
|
if (this.pingSent) {
|
||||||
|
this.handleDisconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pingId += 1;
|
||||||
|
this.pingSent = timestamp();
|
||||||
|
this.socket.send(`ping:${this.pingId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private pong(id: number) {
|
||||||
|
if (!this.pingSent) {
|
||||||
|
console.error('Received a pong without sending a ping first');
|
||||||
|
|
||||||
|
this.handleDisconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id !== this.pingId) {
|
||||||
|
console.error('pingId differs');
|
||||||
|
|
||||||
|
this.handleDisconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
const latency = timestamp() - this.pingSent;
|
||||||
|
this.pingSent = null;
|
||||||
|
|
||||||
|
console.log('latency', latency);
|
||||||
|
|
||||||
|
this.pingTimeout = setTimeout(this.ping, 30000);
|
||||||
|
}
|
||||||
|
|
||||||
private clean() {
|
private clean() {
|
||||||
|
clearTimeout(this.pingTimeout);
|
||||||
|
|
||||||
this.socket.removeEventListener('message', this.handleMessages);
|
this.socket.removeEventListener('message', this.handleMessages);
|
||||||
this.socket.removeEventListener('close', this.handleDisconnect);
|
this.socket.removeEventListener('close', this.handleDisconnect);
|
||||||
this.socket.removeEventListener('error', this.handleDisconnect);
|
this.socket.removeEventListener('error', this.handleDisconnect);
|
||||||
@@ -223,6 +263,12 @@ export class Connection {
|
|||||||
continue messages;
|
continue messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Actions.Pong: {
|
||||||
|
this.pong(Number(message.payload));
|
||||||
|
|
||||||
|
continue messages;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
continue messages;
|
continue messages;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user