type WebsocketData = { clientId: string } type Message = | { type: 'welcome', id: string } | { type: 'presence-information', others: number } | { type: 'ripple', position: [number, number], maxRadius: number } const clients: Map = new Map() const _server = Deno.serve({ port: Number.parseInt(Deno.env.get('PORT') || '8000', 10), handler: (req) => { if (req.headers.get("upgrade") !== "websocket") { return new Response(null, { status: 501 }) } const { socket, response } = Deno.upgradeWebSocket(req) // TODO Allow creating private ponds const clientId = crypto.randomUUID() console.log('generated clientId', clientId) socket.addEventListener("open", () => { // register newly connected client and tell them how many other people are there console.log('Connection opened', clientId, clients) socket.send(JSON.stringify({ type: 'welcome', id: clientId })) const enterNotice = JSON.stringify({ type: 'presence-information', others: clients.size, }) clients.set(clientId, socket) for (const client of clients.values()) { client.send(enterNotice) } }) socket.addEventListener("message", (event) => { const message = `${event.data}` // broadcast message to all other clients // TODO: Validate message shape const msg = JSON.parse(`${message}`) console.log('Relaying message from', clientId, msg) for (const [uuid, client] of clients.entries()) { if (uuid !== clientId) { client.send(message) } } }) socket.addEventListener("close", () => { // remove client from list of registered clients and tell other clients how many people are there console.log('Connection closed', clientId, clients) clients.delete(clientId) const leaveNotice = JSON.stringify({ type: 'presence-information', others: clients.size - 1, }) for (const [uuid, client] of clients.entries()) { if (uuid !== clientId) { client.send(leaveNotice) } } }) return response } })