create websocket cache server

This commit is contained in:
2024-09-28 08:30:55 -07:00
commit 172fe69359
8 changed files with 335 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
export class WebSocketLifecycle {
cachedValue: string = "";
reconnectTimer?: Timer;
socket?: WebSocket;
readonly socketUrl: string;
readonly name: string;
private messages: string[];
constructor(socketUrl: string, name: string) {
this.name = name;
this.socketUrl = socketUrl;
this.messages = [""];
}
public registerWebSocketHandler() {
this.socket = new WebSocket(this.socketUrl);
// message is received
this.socket.addEventListener("message", event => {
console.log(`WS: ${this.socketUrl} got message`, event)
this.messages = [event.data];
});
// socket opened
this.socket.addEventListener("open", event => {
console.log(`WS: ${this.socketUrl} opened`);
if (this.reconnectTimer) {
console.log(`WS: ${this.socketUrl} cancelling reconnect timer`)
clearInterval(this.reconnectTimer);
this.reconnectTimer = undefined;
}
});
// socket closed
this.socket.addEventListener("close", event => {
console.log(`WS: ${this.socketUrl} closed`);
if (!this.reconnectTimer) {
console.log(`WS: ${this.socketUrl} scheduling reconnect every 5s`);
this.reconnectTimer = setInterval(() => {
console.log(`WS: ${this.socketUrl} trying to reconnect`);
this.registerWebSocketHandler();
}, 5000);
}
});
// error handler
this.socket.addEventListener("error", event => {
console.error(`WS: ${this.socketUrl} error: `, event);
});
}
public getLatestMessage(): any {
return JSON.parse(this.messages[0]);
}
}
+37
View File
@@ -0,0 +1,37 @@
import { Hono } from "hono";
import { prettyJSON } from "hono/pretty-json";
import { serve } from "bun";
import type { WebSocketLifecycle } from "./WebSocketLifeCycle";
export class WebhookServer {
readonly app: Hono;
readonly websockets: WebSocketLifecycle[];
constructor(websockets: WebSocketLifecycle[]) {
this.websockets = websockets;
this.app = new Hono();
this.app.use(prettyJSON());
this.app.get(`/api/:wsName`, async (c) => {
const wsName = c.req.param('wsName');
const webSocket = this.websockets.find(ws => ws.name === wsName);
if (!webSocket) {
return c.json({
err: "unknown websocket",
}, 404);
}
return c.json(webSocket.getLatestMessage(), 200);
});
}
listen(port: number) {
return serve({
fetch: this.app.fetch,
port,
});
}
}
+8
View File
@@ -0,0 +1,8 @@
import { WebhookServer } from "./WebhookServer";
import { WebSocketLifecycle } from "./WebSocketLifeCycle";
const socket = new WebSocketLifecycle("wss://ntfy.chromart.cc/buzzer/ws", "buzzer");
socket.registerWebSocketHandler();
const wsServer = new WebhookServer([socket]);
wsServer.listen(8080);