Automatic reconnect to server with exp backoff

This commit is contained in:
Radon Rosborough 2020-06-07 16:24:45 -06:00
parent b31e49d40d
commit 76a1c8fa1d
1 changed files with 63 additions and 46 deletions

View File

@ -14,56 +14,73 @@ term.open(document.getElementById("terminal"));
fitAddon.fit();
window.addEventListener("resize", () => fitAddon.fit());
const socket = new WebSocket(
(document.location.protocol === "http:" ? "ws://" : "wss://") +
document.location.host +
`/api/v1/ws?lang=${lang}`
);
const initialRetryDelayMs = 200;
let retryDelayMs = initialRetryDelayMs;
socket.addEventListener("open", () =>
console.log("Successfully connected to server")
);
socket.addEventListener("message", (event) => {
let message: any;
try {
message = JSON.parse(event.data);
} catch (err) {
console.error("Malformed message from server:", event.data);
return;
}
switch (message?.event) {
case "terminalClear":
term.reset();
function tryConnect() {
console.log("Connecting to server...");
socket = new WebSocket(
(document.location.protocol === "http:" ? "ws://" : "wss://") +
document.location.host +
`/api/v1/ws?lang=${lang}`
);
socket.addEventListener("open", () => {
retryDelayMs = initialRetryDelayMs;
console.log("Successfully connected to server");
});
socket.addEventListener("message", (event: MessageEvent) => {
let message: any;
try {
message = JSON.parse(event.data);
} catch (err) {
console.error("Malformed message from server:", event.data);
return;
case "terminalOutput":
if (typeof message.output !== "string") {
}
switch (message?.event) {
case "terminalClear":
term.reset();
return;
case "terminalOutput":
if (typeof message.output !== "string") {
console.error("Unexpected message from server:", message);
return;
}
term.write(message.output);
return;
case "setMonacoLanguage":
if (typeof message.monacoLanguage !== "string") {
console.error("Unexpected message from server:", message);
return;
}
monaco.editor.setModelLanguage(
editor.getModel(),
message.monacoLanguage
);
return;
default:
console.error("Unexpected message from server:", message);
return;
}
term.write(message.output);
return;
case "setMonacoLanguage":
if (typeof message.monacoLanguage !== "string") {
console.error("Unexpected message from server:", message);
return;
}
monaco.editor.setModelLanguage(editor.getModel(), message.monacoLanguage);
return;
default:
console.error("Unexpected message from server:", message);
return;
}
});
socket.addEventListener("close", (event) => {
if (event.wasClean) {
console.log("Connection closed cleanly");
} else {
console.error("Connection died");
}
});
socket.addEventListener("onerror", (event) =>
console.error("Connection error:", event)
);
}
});
socket.addEventListener("close", (event: CloseEvent) => {
if (event.wasClean) {
console.log("Connection closed cleanly");
} else {
console.error("Connection died");
}
scheduleConnect();
});
}
function scheduleConnect() {
const delay = retryDelayMs * Math.random();
console.log(`Trying to reconnect in ${Math.floor(delay)}ms`);
setTimeout(tryConnect, delay);
retryDelayMs *= 2;
}
let socket = null;
tryConnect();
term.onData((data) =>
socket.send(JSON.stringify({ event: "terminalInput", input: data }))