#!/usr/bin/env -S deno run -A import { BufReader, readLines } from "https://deno.land/std/io/mod.ts"; import { serve } from "https://deno.land/std/http/server.ts"; import { acceptWebSocket, WebSocket, isWebSocketPingEvent, isWebSocketCloseEvent } from "https://deno.land/std/ws/mod.ts" import { v4 } from 'https://deno.land/std/uuid/mod.ts'; let enc = new TextEncoder(); let dec = new TextDecoder(); const WS = new Map() function broadcast(message: string) { WS.forEach((ws)=>{ ws.send(message); }); } async function handleWs(ws: WebSocket) { const uid = v4.generate(); WS.set(uid, ws); console.log('ws connected', uid); for await (const event of ws) { if (typeof event === 'string') { let msg = event; // console.log(event); broadcast(msg); } if (event instanceof Uint8Array){ let msg = dec.decode(event); // console.log(dec.decode(event)) broadcast(msg); } if (isWebSocketPingEvent(event)){ console.log('ping', event) } if (isWebSocketCloseEvent(event)){ console.log('close', event) break } } console.log('bye') WS.delete(uid); } for await (const req of serve({port: 8080})) { // req.respond({body: "Hello World!"}); console.log(req); if (req.headers.get("upgrade") == "websocket") { const { conn, r: bufReader, w: bufWriter, headers } = req; acceptWebSocket({ conn, bufReader, bufWriter, headers, }).then(handleWs) } } let ln = Deno.listen({hostname: "0.0.0.0", port: 8080, transport: "tcp"}); let addr = ln.addr as Deno.NetAddr; console.log(`listening on ${addr.hostname}:${addr.port}`); for (var id = 0; id < 10; id ++) { let conn = await ln.accept(); let addr = conn.remoteAddr as Deno.NetAddr; console.log(`client[${id}] connected from ${addr.hostname}:${addr.port}`); readclose(conn, id); write(conn, id); } async function readclose(conn: Deno.Reader | Deno.Closer, id: number){ let scanner = new BufReader(conn as Deno.Reader); for (;;) { try { let line = await scanner.readString('\n'); if (line == null) { console.log(`client[${id}] disconnected: read: EOF`); break; } console.log(`client[${id}]: ${line}`); } catch (e) { console.log(`client[${id}] connected: read: ${e.message}`); break; } } (conn as Deno.Closer).close(); } async function write(conn: Deno.Writer, id: number){ for (;;) { let msg = `client[${id}]: stf\n`; let buf = enc.encode(msg); try { await conn.write(buf); } catch (e) { console.log(`client[${id}] disconnected: write: ${e.message}`); break; } await delay(1000); } } function delay(ms: number) { return new Promise( resolve => setTimeout(resolve, ms) ); }