From 2e584fff323826ab65577fd2443ce65002e48b25 Mon Sep 17 00:00:00 2001 From: Halit Aksoy Date: Sat, 16 Jul 2022 17:16:41 +0300 Subject: [PATCH] add ping pong --- src/rtmt/rtmt_websocket.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/rtmt/rtmt_websocket.ts b/src/rtmt/rtmt_websocket.ts index bbecfec..f0da39b 100644 --- a/src/rtmt/rtmt_websocket.ts +++ b/src/rtmt/rtmt_websocket.ts @@ -1,11 +1,16 @@ import { decode, encode } from "./encode_decode_message"; import { Bytes, OnMessage, RTMT } from "./rtmt"; import { server } from "../service/http_service"; +import { channel_ping, channel_pong } from "../const/channel_names"; + +const PING_INTERVAL = 3000, PING_INTERVAL_BUFFER_TIME = 500; export class RTMTWS implements RTMT { private messageChannels: Map; private ws: WebSocket; + private pingTimeout?: number = undefined; + constructor() { this.messageChannels = new Map(); } @@ -22,11 +27,13 @@ export class RTMTWS implements RTMT { ws.onopen = () => { console.info("(RTMT) ws has opened"); this.ws = ws; + this.heartbeat(); onopen(); }; ws.onclose = () => { console.info("(RTMT) ws has closed"); //this.ws = undefined + clearTimeout(this.pingTimeout); onClose(); }; @@ -40,6 +47,20 @@ export class RTMTWS implements RTMT { }); } + heartbeat() { + clearTimeout(this.pingTimeout); + + // Use `WebSocket#terminate()`, which immediately destroys the connection, + // instead of `WebSocket#close()`, which waits for the close timer. + // Delay should be equal to the interval at which your server + // sends out pings plus a conservative assumption of the latency. + this.pingTimeout = setTimeout(() => { + this.ws.close(); + this.ws.onclose?.(new CloseEvent("CONNECTION_LOST")); + }, PING_INTERVAL + PING_INTERVAL_BUFFER_TIME); + } + + sendMessage(channel: string, message: Object) { if (this.ws === undefined) { console.error("(RTMT) ws is undefined"); @@ -59,6 +80,11 @@ export class RTMTWS implements RTMT { } onMessage(channel: string, message: Bytes) { + if(channel === channel_ping) { + this.heartbeat(); + this.sendMessage(channel_pong, {}); + return; + } const callback = this.messageChannels.get(channel); if (callback) {