mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-21 16:38:23 +01:00
add ws reconnect handlers -- wps + route announcements
This commit is contained in:
parent
9bf30ce121
commit
dbdcc49ff2
@ -24,6 +24,12 @@ type WaveEventUnsubscribe = {
|
||||
const fileSubjects = new Map<string, SubjectWithRef<WSFileEventData>>();
|
||||
const waveEventSubjects = new Map<string, WaveEventSubjectContainer[]>();
|
||||
|
||||
function wpsReconnectHandler() {
|
||||
for (const eventType of waveEventSubjects.keys()) {
|
||||
updateWaveEventSub(eventType);
|
||||
}
|
||||
}
|
||||
|
||||
function makeWaveReSubCommand(eventType: string): RpcMessage {
|
||||
let subjects = waveEventSubjects.get(eventType);
|
||||
if (subjects == null) {
|
||||
@ -134,4 +140,4 @@ function handleWaveEvent(event: WaveEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
export { getFileSubject, handleWaveEvent, waveEventSubscribe, waveEventUnsubscribe };
|
||||
export { getFileSubject, handleWaveEvent, waveEventSubscribe, waveEventUnsubscribe, wpsReconnectHandler };
|
||||
|
@ -1,9 +1,24 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import debug from "debug";
|
||||
import { sprintf } from "sprintf-js";
|
||||
|
||||
const dlog = debug("wave:ws");
|
||||
|
||||
const MaxWebSocketSendSize = 1024 * 1024; // 1MB
|
||||
const reconnectHandlers: (() => void)[] = [];
|
||||
|
||||
function addWSReconnectHandler(handler: () => void) {
|
||||
reconnectHandlers.push(handler);
|
||||
}
|
||||
|
||||
function removeWSReconnectHandler(handler: () => void) {
|
||||
const index = this.reconnectHandlers.indexOf(handler);
|
||||
if (index > -1) {
|
||||
reconnectHandlers.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
type WSEventCallback = (arg0: WSEventType) => void;
|
||||
|
||||
@ -29,20 +44,12 @@ class WSControl {
|
||||
setInterval(this.sendPing.bind(this), 5000);
|
||||
}
|
||||
|
||||
log(str: string) {
|
||||
const ts = Date.now();
|
||||
this.wsLog.push("[" + ts + "] " + str);
|
||||
if (this.wsLog.length > 50) {
|
||||
this.wsLog.splice(0, this.wsLog.length - 50);
|
||||
}
|
||||
}
|
||||
|
||||
connectNow(desc: string) {
|
||||
if (this.open) {
|
||||
return;
|
||||
}
|
||||
this.lastReconnectTime = Date.now();
|
||||
this.log(sprintf("try reconnect (%s)", desc));
|
||||
dlog("try reconnect:", desc);
|
||||
this.opening = true;
|
||||
this.wsConn = new WebSocket(this.baseHostPort + "/ws?windowid=" + this.windowId);
|
||||
this.wsConn.onopen = this.onopen.bind(this);
|
||||
@ -61,7 +68,7 @@ class WSControl {
|
||||
}
|
||||
this.reconnectTimes++;
|
||||
if (this.reconnectTimes > 20) {
|
||||
this.log("cannot connect, giving up");
|
||||
dlog("cannot connect, giving up");
|
||||
return;
|
||||
}
|
||||
const timeoutArr = [0, 0, 2, 5, 10, 10, 30, 60];
|
||||
@ -73,7 +80,7 @@ class WSControl {
|
||||
timeout = 1;
|
||||
}
|
||||
if (timeout > 0) {
|
||||
this.log(sprintf("sleeping %ds", timeout));
|
||||
dlog(sprintf("sleeping %ds", timeout));
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.connectNow(String(this.reconnectTimes));
|
||||
@ -83,9 +90,9 @@ class WSControl {
|
||||
onclose(event: any) {
|
||||
// console.log("close", event);
|
||||
if (event.wasClean) {
|
||||
this.log("connection closed");
|
||||
dlog("connection closed");
|
||||
} else {
|
||||
this.log("connection error/disconnected");
|
||||
dlog("connection error/disconnected");
|
||||
}
|
||||
if (this.open || this.opening) {
|
||||
this.open = false;
|
||||
@ -95,9 +102,12 @@ class WSControl {
|
||||
}
|
||||
|
||||
onopen() {
|
||||
this.log("connection open");
|
||||
dlog("connection open");
|
||||
this.open = true;
|
||||
this.opening = false;
|
||||
for (let handler of reconnectHandlers) {
|
||||
handler();
|
||||
}
|
||||
this.runMsgQueue();
|
||||
// reconnectTimes is reset in onmessage:hello
|
||||
}
|
||||
@ -174,4 +184,4 @@ class WSControl {
|
||||
}
|
||||
}
|
||||
|
||||
export { WSControl };
|
||||
export { addWSReconnectHandler, removeWSReconnectHandler, WSControl };
|
||||
|
@ -34,6 +34,17 @@ class WshRouter {
|
||||
this.upstreamClient = upstreamClient;
|
||||
}
|
||||
|
||||
reannounceRoutes() {
|
||||
for (const [routeId, client] of this.routeMap) {
|
||||
const announceMsg: RpcMessage = {
|
||||
command: "routeannounce",
|
||||
data: routeId,
|
||||
source: routeId,
|
||||
};
|
||||
this.upstreamClient.recvRpcMessage(announceMsg);
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if the message was sent
|
||||
_sendRoutedMessage(msg: RpcMessage, destRouteId: string): boolean {
|
||||
const client = this.routeMap.get(destRouteId);
|
||||
|
@ -1,10 +1,11 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { wpsReconnectHandler } from "@/app/store/wps";
|
||||
import { WshClient } from "@/app/store/wshclient";
|
||||
import { makeWindowRouteId, WshRouter } from "@/app/store/wshrouter";
|
||||
import { getWSServerEndpoint } from "@/util/endpoints";
|
||||
import { WSControl } from "./ws";
|
||||
import { addWSReconnectHandler, WSControl } from "./ws";
|
||||
|
||||
let globalWS: WSControl;
|
||||
let DefaultRouter: WshRouter;
|
||||
@ -113,7 +114,7 @@ if (globalThis.window != null) {
|
||||
globalThis["consumeGenerator"] = consumeGenerator;
|
||||
}
|
||||
|
||||
function initWshrpc(windowId: string) {
|
||||
function initWshrpc(windowId: string): WSControl {
|
||||
DefaultRouter = new WshRouter(new UpstreamWshRpcProxy());
|
||||
const handleFn = (event: WSEventType) => {
|
||||
DefaultRouter.recvRpcMessage(event.data);
|
||||
@ -123,6 +124,11 @@ function initWshrpc(windowId: string) {
|
||||
globalWS.connectNow("connectWshrpc");
|
||||
WindowRpcClient = new WshClient(makeWindowRouteId(windowId));
|
||||
DefaultRouter.registerRoute(WindowRpcClient.routeId, WindowRpcClient);
|
||||
addWSReconnectHandler(() => {
|
||||
DefaultRouter.reannounceRoutes();
|
||||
});
|
||||
addWSReconnectHandler(wpsReconnectHandler);
|
||||
return globalWS;
|
||||
}
|
||||
|
||||
function sendWSCommand(cmd: WSCommandType) {
|
||||
|
@ -59,7 +59,8 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
console.log("DOMContentLoaded");
|
||||
|
||||
// Init WPS event handlers
|
||||
initWshrpc(windowId);
|
||||
const globalWS = initWshrpc(windowId);
|
||||
(window as any).globalWS = globalWS;
|
||||
(window as any).WindowRpcClient = WindowRpcClient;
|
||||
await loadConnStatus();
|
||||
initGlobalWaveEventSubs();
|
||||
|
Loading…
Reference in New Issue
Block a user