feat: Add websocket handling

Added websocket functionality for keeping the connection alive and handling events.
This commit is contained in:
Ayane Satomi 2023-10-23 13:22:03 +00:00
parent 866965acc9
commit cdf547e4bd
2 changed files with 42 additions and 8 deletions

View file

@ -99,6 +99,22 @@ export default function Counter(props: SharedProps) {
}; };
const handleWSEvents = (ws: WebSocket) => { const handleWSEvents = (ws: WebSocket) => {
const heartbeatFunc = (fName: number) => {
if (ws.readyState === 1) ws.send((0x0).toString());
// do nothing because you can do nothing
else return;
};
const tmFunc = () => {
console.warn("Server is down, reconnecting...");
ws.close();
ws = new WebSocket(window.location.href.replace("http", "ws"));
handleWSEvents(ws);
};
let heartbeat = setInterval(() => heartbeatFunc(heartbeat), 15000);
let tm = setTimeout(tmFunc, 30000);
ws.onopen = () => { ws.onopen = () => {
console.log( console.log(
`[${new Date().toISOString()}] Connected to statistics socket`, `[${new Date().toISOString()}] Connected to statistics socket`,
@ -106,24 +122,36 @@ export default function Counter(props: SharedProps) {
}; };
ws.onmessage = (e) => { ws.onmessage = (e) => {
console.log( switch (e.data) {
`[${new Date().toISOString()}] Received global count: ${e.data}`, case (0x1).toString():
); console.log("Received Keepalive from server.");
clearTimeout(tm);
clearInterval(heartbeat);
heartbeat = setInterval(() => heartbeatFunc(heartbeat), 15000);
tm = setTimeout(tmFunc, 30000);
break;
default: {
const data = JSON.parse(e.data); const data = JSON.parse(e.data);
setGlobalCount(BigInt(parseInt(data.globalCount))); setGlobalCount(BigInt(parseInt(data.globalCount)));
}
}
}; };
ws.onclose = () => { ws.onclose = () => {
console.warn(`[${new Date().toISOString()}] Disconnected from statistics socket.`,); console.warn(
`[${new Date().toISOString()}] Disconnected from statistics socket.`,
);
}; };
ws.onerror = (e) => { ws.onerror = (e) => {
console.error(`[${new Date().toISOString()}] Socket Errored. ${e.type}`,); console.error(`[${new Date().toISOString()}] Socket Errored. ${e.type}`);
};
}; };
}
useEffect(() => { useEffect(() => {
let ws = new WebSocket(window.location.href.replace("http", "ws")); let ws = new WebSocket(window.location.href.replace("http", "ws"));
handleWSEvents(ws); handleWSEvents(ws);
const onlineHandler = () => { const onlineHandler = () => {
@ -146,6 +174,7 @@ export default function Counter(props: SharedProps) {
return () => { return () => {
globalThis.window.removeEventListener("online", onlineHandler); globalThis.window.removeEventListener("online", onlineHandler);
globalThis.window.removeEventListener("offline", offlineHandler); globalThis.window.removeEventListener("offline", offlineHandler);
handleWSEvents(ws);
ws.close(); ws.close();
}; };
}, []); }, []);

View file

@ -42,6 +42,11 @@ export const handler: Handlers = {
} }
}); });
socket.onmessage = (e) => {
// client will send 0x0 as a string, send back 0x1 as a string to confirm the connection is alive
if (e.data === 0x0.toString()) socket.send(0x1.toString());
}
socket.onclose = () => { socket.onclose = () => {
bc.close(); bc.close();
console.log( console.log(