import { JsonParseStream } from "https://deno.land/std@0.157.0/encoding/json/stream.ts"; import { TextLineStream } from "https://deno.land/std@0.156.0/streams/delimiter.ts"; const PORT = 5588; const tEnc = new TextEncoder(); console.log(`Listening on port ${PORT}`); for await (const conn of Deno.listen({ port: PORT })) { processRequestStream(conn); } async function processRequestStream(conn: Deno.Conn) { console.log("Connection established:", conn.remoteAddr); try { for await (const request of requests(conn)) { console.debug("Request:", request); if ( request == null || typeof request != "object" || !("method" in request) || !("number" in request) ) { throw "Invalid request"; } if ( request.method == "isPrime" && typeof request.number == "number" ) { const response = { method: "isPrime", prime: isPrime(request.number), }; console.debug("Response:", response); conn.write(tEnc.encode(JSON.stringify(response) + "\n")); } else { console.debug("Request malformed"); conn.write(tEnc.encode("Malformed!\n")); } } } catch (e) { console.error(conn.remoteAddr, e); } finally { console.log("Connection closed:", conn.remoteAddr); try { conn.close(); } catch (_err) { // connection already closed } } } function isPrime(n: number) { if (!Number.isInteger(n)) return false; for (let i = 2, s = Math.sqrt(n); i <= s; i++) if (n % i === 0) return false; return n > 1; } function requests(conn: Deno.Conn) { try { const readable = conn.readable .pipeThrough(new TextDecoderStream()) .pipeThrough(new TextLineStream()) .pipeThrough(new JsonParseStream()); return { async *[Symbol.asyncIterator]() { for await (const data of readable) { yield data; } }, }; } catch (err) { console.error(err); } }