/// export function startServer( hostname: string = "localhost", port: number = 8042, ): () => Promise { let nextId = 1; const clientsMap = new Map(); const clientRoomMap = new Map(); const roomsMap = new Map(); const broadcast = (room: string, message: string): void => { const members = roomsMap.get(room)!; for (const member of members) { const socket = clientsMap.get(member); if (socket && socket.readyState === WebSocket.OPEN) { socket.send(message); } } }; const commands = { join: (id: number, args: string[]) => { const room = args[0]; if (roomsMap.has(room)) { roomsMap.get(room)!.push(id); } else { roomsMap.set(room, [id]); } clientRoomMap.getOrInsert(id, room); // not sure about that broadcast(room, `${id} has joined!`); }, } as const; const handleConnection = (socket: WebSocket): void => { const id = nextId++; socket.onopen = () => { clientsMap.set(id, socket); socket.send(`Welcome ${id}, type /join .`); }; socket.onclose = () => { const room = clientRoomMap.get(id); if (room) { clientRoomMap.delete(id); const members = roomsMap.get(room)!; members.splice(members.indexOf(id), 1); broadcast(room, `${id} has left!`); } clientsMap.delete(id); }; socket.onmessage = (message: MessageEvent) => { const text = String(message.data); if (text.startsWith("/")) { const [command, ...args] = text.substring(1).split(" "); try { // @ts-ignore commands[command](id, args); } catch (error) { socket.send(JSON.stringify(error)); } } }; socket.onerror = console.error; }; const ac = new AbortController(); const server = Deno.serve( { hostname, port, signal: ac.signal }, (request) => { if (request.headers.get("upgrade") !== "websocket") { return new Response("Upgrade Required", { status: 426 }); } const { socket, response } = Deno.upgradeWebSocket(request); handleConnection(socket); return response; }, ); return () => { ac.abort(); return server.finished; }; }