lotsa stuff
This commit is contained in:
123
deno/server.ts
123
deno/server.ts
@@ -1,34 +1,46 @@
|
||||
// TODO
|
||||
// Peer mssages
|
||||
// Routing
|
||||
// Video files being fully sent
|
||||
// Use Deno static serving for static
|
||||
// TODO: server
|
||||
// Peer mssages ✅
|
||||
// Routing ✅
|
||||
// Video files being fully sent ❓
|
||||
// Use Deno static serving for static ✅
|
||||
// Use Workers, at least for serving static files. Why not nginx? Single binary server.
|
||||
|
||||
import { serveDir } from "jsr:@std/http/file-server"
|
||||
|
||||
// deno-lint-ignore-file prefer-const no-explicit-any
|
||||
function serveFile(filename: string) {
|
||||
// console.log(filename)
|
||||
const responseText = Deno.readFileSync("../" + filename);
|
||||
// console.log(responseText)
|
||||
const response = new Response(responseText);
|
||||
|
||||
if (filename.endsWith('.js')) {
|
||||
response.headers.set('content-type', 'application/javascript')
|
||||
const memoryResponseMap: Map<string, Response> = new Map();
|
||||
// deno-lint-ignore-file prefer-const no-explicit-any
|
||||
async function serveFile(filename: string) {
|
||||
// console.log(filename)
|
||||
|
||||
const response = memoryResponseMap.get(filename);
|
||||
|
||||
if (response) {
|
||||
return response.clone();
|
||||
}
|
||||
return response;
|
||||
|
||||
|
||||
const file = await Deno.readFile("../" + filename);
|
||||
const newResponse = new Response(file);
|
||||
if (filename.endsWith('.js')) {
|
||||
newResponse.headers.set('content-type', 'application/javascript')
|
||||
}
|
||||
|
||||
memoryResponseMap.set(filename, newResponse);
|
||||
|
||||
return newResponse.clone();
|
||||
}
|
||||
|
||||
function hashIdToNumber(id: string, range:number) {
|
||||
function hashIdToNumber(id: string, range: number) {
|
||||
let number = 0;
|
||||
let hash = 0x811c9dc5
|
||||
for (let char of id) {
|
||||
if (char !== '0' && char !== '-') {
|
||||
hash ^= char.charCodeAt(0);
|
||||
hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
|
||||
if (char !== '0' && char !== '-') {
|
||||
hash ^= char.charCodeAt(0);
|
||||
hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return (hash >>> 0) % range;
|
||||
}
|
||||
@@ -36,16 +48,23 @@ function hashIdToNumber(id: string, range:number) {
|
||||
const colors = [
|
||||
160, 196, 202, 208, 214, 220, 226, 190, 154, 118, 82, 46, 47, 48, 49,
|
||||
51, 45, 44, 43, 42, 41, 40, 39, 33, 27, 21, 57, 93, 129, 165, 201,
|
||||
];
|
||||
];
|
||||
|
||||
const resetCode = "\x1b[0m";
|
||||
function colorID(id) {
|
||||
function colorID(id: string) {
|
||||
if (typeof id !== 'string') {
|
||||
console.error(`colorID: expected string but got `, id);
|
||||
return "";
|
||||
}
|
||||
const colorCode = `\x1b[38;5;${colors[hashIdToNumber(id, colors.length)]}m`
|
||||
return `${colorCode}${id.substring(0,5)}${resetCode}`
|
||||
return `${colorCode}${id.substring(0, 5)}${resetCode}`
|
||||
}
|
||||
|
||||
|
||||
function pingHandler(m: any) {
|
||||
console.log(colorID(m.peer_id), "pong handler", m);
|
||||
let time = Temporal.Now.zonedDateTimeISO();
|
||||
// console.log("ping", m);
|
||||
console.log(time, `ping handler ${colorID(m.peer_id)}:${m.peer_name} ${colorID(m.user_id)}:${m.user_name}`);
|
||||
return '{"type":"pong"}'
|
||||
}
|
||||
|
||||
@@ -73,20 +92,24 @@ function helloHandler(m: HelloMessage, socket: WebSocket) {
|
||||
peerSockets.set(m.peer_id, socket);
|
||||
socketPeers.set(socket, m.peer_id);
|
||||
|
||||
if (Symbol.iterator in Object(m.known_users)) {
|
||||
for (const knownUserID of m.known_users) {
|
||||
console.log(`Adding user ${knownUserID} from peer ${colorID(m.peer_id)}`);
|
||||
if (!userPeers.get(knownUserID)) {
|
||||
userPeers.set(knownUserID, new Set());
|
||||
}
|
||||
|
||||
for (const knownUserID of m.known_users) {
|
||||
console.log(`Adding user ${knownUserID} from peer ${colorID(m.peer_id)}`);
|
||||
if (!userPeers.get(knownUserID)) {
|
||||
userPeers.set(knownUserID, new Set());
|
||||
userPeers.get(knownUserID)?.add(m.peer_id);
|
||||
}
|
||||
|
||||
userPeers.get(knownUserID)?.add(m.peer_id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
let returnValue: any = {};
|
||||
for (let key of userPeers.keys()) {
|
||||
let peers = userPeers.get(key);
|
||||
if (!peers) {
|
||||
if (!peers || peers.size === 0) {
|
||||
continue;
|
||||
}
|
||||
returnValue[key] = [...peers.keys()];
|
||||
@@ -124,6 +147,7 @@ function peerMessageHandler(m: PeerMessage, _socket: WebSocket) {
|
||||
|
||||
if (toPeer.readyState !== WebSocket.OPEN) {
|
||||
console.log("Peer socket is not open:", toPeer);
|
||||
deletePeerFromUserPeers(m.to);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -135,14 +159,24 @@ function peerMessageHandler(m: PeerMessage, _socket: WebSocket) {
|
||||
|
||||
const messageDispatch: Map<string, (m: any, socket: WebSocket) => string | null> = new Map();
|
||||
|
||||
function deletePeerFromUserPeers(peerIDToDelete: string) {
|
||||
for (let [userID, peers] of userPeers.entries()) {
|
||||
for (let peerID of peers) {
|
||||
if (peerID === peerIDToDelete) {
|
||||
peers.delete(peerIDToDelete);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function connectWebsocket(request: Request) {
|
||||
if (request.headers.get("upgrade") != "websocket") {
|
||||
return new Response(null, { status: 501 });
|
||||
}
|
||||
|
||||
const { socket, response } = Deno.upgradeWebSocket(request);
|
||||
socket.addEventListener("open", () => {
|
||||
console.log("a client connected!");
|
||||
socket.addEventListener("open", (event) => {
|
||||
console.log("New peer websocket connection");
|
||||
});
|
||||
socket.addEventListener("message", (event) => {
|
||||
// console.log(event);
|
||||
@@ -169,8 +203,16 @@ function connectWebsocket(request: Request) {
|
||||
|
||||
});
|
||||
|
||||
socket.addEventListener("close", (event) => {
|
||||
socket.addEventListener("close", (event: CloseEvent) => {
|
||||
let peerID = socketPeers.get(socket);
|
||||
if (!peerID) {
|
||||
console.log("Websocket close: couldn't find peer 🤔");
|
||||
return;
|
||||
}
|
||||
console.log("Websocket close:", colorID(peerID), `code:${event.code} reason:${event.reason} wasClean: ${event.wasClean}`);
|
||||
|
||||
peerSockets.delete(peerID);
|
||||
deletePeerFromUserPeers(peerID);
|
||||
});
|
||||
|
||||
return response;
|
||||
@@ -178,10 +220,19 @@ function connectWebsocket(request: Request) {
|
||||
}
|
||||
|
||||
function handler(request: Request, info: any) {
|
||||
if (request.url === "https://ddln.app/") {
|
||||
return serveFile("/static/index.html")
|
||||
}
|
||||
|
||||
// console.log(info.remoteAddr);
|
||||
console.log(info.remoteAddr.hostname, request.url, request.headers.get('user-agent'));
|
||||
|
||||
const url = new URL(request.url);
|
||||
|
||||
if (url.pathname.endsWith('mp4') || url.pathname.endsWith('webm')) {
|
||||
console.log("Not serving video...");
|
||||
return new Response("Not serving video", { status: 404 });
|
||||
}
|
||||
|
||||
if (url.pathname === "/") {
|
||||
return serveFile("/static/index.html")
|
||||
}
|
||||
@@ -195,7 +246,7 @@ function handler(request: Request, info: any) {
|
||||
return serveFile("static/sw.js")
|
||||
}
|
||||
|
||||
if (url.pathname === "/robots).txt") {
|
||||
if (url.pathname === "/robots.txt") {
|
||||
return serveFile("static/robots.txt")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user