74 lines
1.9 KiB
TypeScript
74 lines
1.9 KiB
TypeScript
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);
|
|
}
|
|
}
|