129 lines
5.3 KiB
TypeScript
129 lines
5.3 KiB
TypeScript
import type { ServerWebSocket } from "bun";
|
|
import { callTicket, completeTicket, getCurrentTicket, getDisplayTickets, getLogEntries, getTicket, noShowTicket } from "./redis";
|
|
|
|
let IP_TO_ROOMS: Record<string, string> = {};
|
|
|
|
const iprooms = await Bun.file("./iprooms.csv").text();
|
|
const lines = iprooms.split("\n");
|
|
for (const line of lines.slice(1)) {
|
|
const [ip, room] = line.split(",");
|
|
if (ip && room) {
|
|
IP_TO_ROOMS[ip.trim()] = room.trim();
|
|
}
|
|
}
|
|
|
|
export let displaySockets: ServerWebSocket<unknown>[] = [];
|
|
|
|
export async function broadcastDisplayUpdate() {
|
|
for (const ws of displaySockets) {
|
|
if (ws.readyState === WebSocket.OPEN) {
|
|
ws.send(JSON.stringify({ type: "display", tickets: await getDisplayTickets() }));
|
|
}
|
|
}
|
|
}
|
|
|
|
Bun.serve({
|
|
fetch(req, server) {
|
|
// upgrade the request to a WebSocket
|
|
if (server.upgrade(req)) {
|
|
return; // do not return a Response
|
|
}
|
|
return new Response("Upgrade failed", { status: 500 });
|
|
},
|
|
websocket: {
|
|
async message(ws, message) {
|
|
console.log("Received message:", message);
|
|
const data = JSON.parse(message.toString());
|
|
if (data.type === "hello") {}
|
|
else if (data.type === "my-room") {
|
|
console.log("Client requested room for IP:", ws.remoteAddress);
|
|
const room = IP_TO_ROOMS[ws.remoteAddress];
|
|
if (!room) {
|
|
return void ws.send(JSON.stringify({ type: "error", code: -1, message: "No room" }));
|
|
}
|
|
ws.send(JSON.stringify({ type: "my-room", room }) );
|
|
// } else if (data.type === "create-ticket") {
|
|
// const ticket = await getTicket(data.ticket);
|
|
// if(!ticket || ticket.status == "completed" || ticket.status == "no-show") {
|
|
// await createTicket(data.ticket);
|
|
// ws.send(JSON.stringify({ type: "create-ticket", status: "created", ticket, num: data.ticket }) );
|
|
// return;
|
|
// }
|
|
// ws.send(JSON.stringify({ type: "error", code: -2, message: "Ticket already exists and is not completed or no-show", ticket, num: data.ticket }));
|
|
} else if (data.type === "call-ticket") {
|
|
// const ticket = await getTicket(data.ticket);
|
|
// if(!ticket || ticket.status == "completed" || ticket.status == "no-show") {
|
|
// return void ws.send(JSON.stringify({ type: "error", code: -3, message: "Ticket does not exist or is completed or no-show", ticket, num: data.ticket, room: data.room }) );
|
|
// }
|
|
await callTicket(data.ticket, data.room);
|
|
ws.send(JSON.stringify({ type: "call-ticket", status: "called", ticket: await getTicket(data.ticket), num: data.ticket, room: data.room }) );
|
|
await broadcastDisplayUpdate();
|
|
} else if (data.type === "complete-ticket") {
|
|
const ticket = await getTicket(data.ticket);
|
|
if(ticket?.status !== "called") {
|
|
await completeTicket(data.ticket);
|
|
await broadcastDisplayUpdate();
|
|
return void ws.send(JSON.stringify({ type: "complete-ticket", status: "skipped", ticket, num: data.ticket }) );
|
|
}
|
|
// // Check how long since called
|
|
// const calledDate = new Date(ticket.calledDate || "1970-01-01T00:00:00.000Z");
|
|
// const now = new Date();
|
|
// const diff = now.getTime() - calledDate.getTime();
|
|
// if(diff < 5 * 60 * 1000) { // 5 minutes
|
|
// // Mark as no-show
|
|
// await noShowTicket(data.ticket);
|
|
// await broadcastDisplayUpdate();
|
|
// return void ws.send(JSON.stringify({ type: "complete-ticket", status: "no-show", ticket, num: data.ticket }));
|
|
// }
|
|
|
|
await completeTicket(data.ticket);
|
|
ws.send(JSON.stringify({ type: "complete-ticket", status: "completed", ticket, num: data.ticket }));
|
|
await broadcastDisplayUpdate();
|
|
} else if (data.type === "no-show") {
|
|
const ticket = await getTicket(data.ticket);
|
|
if(!ticket) {
|
|
return;
|
|
}
|
|
// // Check how long since called
|
|
// const calledDate = new Date(ticket.calledDate || "1970-01-01T00:00:00.000Z");
|
|
// const now = new Date();
|
|
// const diff = now.getTime() - calledDate.getTime();
|
|
// if(diff < 5 * 60 * 1000) { // 5 minutes
|
|
// // Mark as no-show
|
|
// await noShowTicket(data.ticket);
|
|
// await broadcastDisplayUpdate();
|
|
// return void ws.send(JSON.stringify({ type: "complete-ticket", status: "no-show", ticket, num: data.ticket }));
|
|
// }
|
|
|
|
await noShowTicket(data.ticket);
|
|
ws.send(JSON.stringify({ type: "complete-ticket", status: "no-show", ticket, num: data.ticket }));
|
|
await broadcastDisplayUpdate();
|
|
} else if (data.type === "get-log") {
|
|
const log = await getLogEntries();
|
|
ws.send(JSON.stringify({ type: "log", log }));
|
|
} else if (data.type === "get-ticket") {
|
|
const ticket = await getTicket(data.ticket);
|
|
ws.send(JSON.stringify({ type: "ticket", ticket, num: data.ticket }));
|
|
} else if (data.type === "get-current-ticket") {
|
|
const ticket = await getCurrentTicket(data.room);
|
|
ws.send(JSON.stringify({ type: "current-ticket", ...ticket, room: data.room }));
|
|
} else if (data.type == "display") {
|
|
if(!displaySockets.includes(ws)) {
|
|
displaySockets.push(ws);
|
|
console.log("Added display socket. Total:", displaySockets.length);
|
|
ws.send(JSON.stringify({ type: "display", tickets: await getDisplayTickets() }));
|
|
}
|
|
}
|
|
}, // a message is received
|
|
open(ws) {
|
|
console.log("WebSocket opened");
|
|
ws.send(JSON.stringify({ type: "hello" }));
|
|
}, // a socket is opened
|
|
close(ws, code, message) {
|
|
console.log("WebSocket closed");
|
|
}, // a socket is closed
|
|
drain(ws) {
|
|
|
|
}, // the socket is ready to receive more data
|
|
}
|
|
}); |