deno server
This commit is contained in:
157
deno/main.ts
157
deno/main.ts
@@ -1,157 +0,0 @@
|
||||
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')
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
function pingHandler(m:any) {
|
||||
console.log("pong handler", m);
|
||||
|
||||
return '{"type":"pong"}'
|
||||
}
|
||||
|
||||
interface HelloMessage {
|
||||
type: string
|
||||
user_id: string
|
||||
user_name: string
|
||||
peer_id:string
|
||||
peer_name: string
|
||||
known_users:string[]
|
||||
|
||||
|
||||
}
|
||||
|
||||
const userPeers:Map<string, Set<string>> = new Map();
|
||||
|
||||
function helloHandler(m:HelloMessage) {
|
||||
console.log(`Received hello from peer ${m.peer_id}:${m.peer_name}, user ${m.user_id}:${m.user_name}`);
|
||||
|
||||
|
||||
if (!userPeers.has(m.user_id)) {
|
||||
userPeers.set(m.user_id, new Set());
|
||||
}
|
||||
userPeers.get(m.user_id)?.add(m.peer_id);
|
||||
|
||||
for (const knownUserID of m.known_users) {
|
||||
console.log(`Adding user ${knownUserID} from peer ${[m.peer_id]}`);
|
||||
if (!userPeers.get(knownUserID)) {
|
||||
userPeers.set(knownUserID, new Set());
|
||||
}
|
||||
|
||||
userPeers.get(knownUserID)?.add(m.peer_id);
|
||||
}
|
||||
|
||||
const peersToReturn = JSON.stringify(userPeers);
|
||||
console.log(peersToReturn);
|
||||
|
||||
return JSON.stringify({type:'hello', userPeers: peersToReturn});
|
||||
}
|
||||
|
||||
const messageDispatch:Map<string, (event:Record<string, never>)=>string> = new Map();
|
||||
|
||||
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("message", (event) => {
|
||||
|
||||
// deno-lint-ignore no-explicit-any
|
||||
let message:any;
|
||||
try {
|
||||
message = JSON.parse(event.data);
|
||||
} catch (e) {
|
||||
console.error("socket.message: ", e);
|
||||
}
|
||||
|
||||
console.log(message);
|
||||
const dispatchHandler = messageDispatch.get(message.type)
|
||||
if (!dispatchHandler) {
|
||||
console.log("Got message I don't understand: ", event.data);
|
||||
return;
|
||||
}
|
||||
|
||||
const response = dispatchHandler(message);
|
||||
console.log(response);
|
||||
socket.send(response);
|
||||
|
||||
});
|
||||
|
||||
return response;
|
||||
|
||||
}
|
||||
|
||||
function handler(request: Request) {
|
||||
|
||||
// console.log(request);
|
||||
|
||||
const url = new URL(request.url);
|
||||
|
||||
if (url.pathname === "/ws") {
|
||||
return connectWebsocket(request);
|
||||
}
|
||||
|
||||
if (url.pathname === "/") {
|
||||
return serveFile("/static/index.html")
|
||||
}
|
||||
|
||||
if (url.pathname === "/sw.js") {
|
||||
return serveFile("static/sw.js")
|
||||
}
|
||||
|
||||
if (url.pathname === "/robots).txt") {
|
||||
return serveFile("static/robots.txt")
|
||||
}
|
||||
|
||||
if (url.pathname === "/favicon.ico") {
|
||||
return serveFile("static/favicon.ico")
|
||||
}
|
||||
|
||||
|
||||
if (url.pathname.includes("/static/")) {
|
||||
return serveFile(url.pathname)
|
||||
}
|
||||
|
||||
// if strings.Contains(r.URL.Path, "/static/") {
|
||||
// log.Print("Serving static")
|
||||
|
||||
// path := filepath.Join(root, r.URL.Path)
|
||||
// info, err := os.Stat(path)
|
||||
// if err != nil || info.IsDir() {
|
||||
// log.Printf("404 File not found/dir")
|
||||
// http.NotFound(w, r)
|
||||
// return
|
||||
// }
|
||||
|
||||
// log.Printf("Serving")
|
||||
// h.ServeHTTP(w, r)
|
||||
// return
|
||||
|
||||
// }
|
||||
|
||||
return new Response("Hello, World!");
|
||||
}
|
||||
|
||||
function main() {
|
||||
|
||||
messageDispatch.set('ping', pingHandler);
|
||||
messageDispatch.set('hello', helloHandler);
|
||||
|
||||
Deno.serve({
|
||||
port: 6789,
|
||||
cert: Deno.readTextFileSync("/etc/letsencrypt/live/ddlion.net/fullchain.pem"),
|
||||
key: Deno.readTextFileSync("/etc/letsencrypt/live/ddlion.net/privkey.pem"),
|
||||
}, handler);
|
||||
}
|
||||
|
||||
main();
|
||||
227
deno/server.ts
Normal file
227
deno/server.ts
Normal file
@@ -0,0 +1,227 @@
|
||||
// TODO
|
||||
// Peer mssages
|
||||
// Routing
|
||||
// Video files being fully sent
|
||||
// Use Deno static serving for static
|
||||
|
||||
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')
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return (hash >>> 0) % range;
|
||||
}
|
||||
|
||||
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) {
|
||||
const colorCode = `\x1b[38;5;${colors[hashIdToNumber(id, colors.length)]}m`
|
||||
return `${colorCode}${id.substring(0,5)}${resetCode}`
|
||||
}
|
||||
|
||||
function pingHandler(m: any) {
|
||||
console.log(colorID(m.peer_id), "pong handler", m);
|
||||
return '{"type":"pong"}'
|
||||
}
|
||||
|
||||
interface HelloMessage {
|
||||
type: string
|
||||
user_id: string
|
||||
user_name: string
|
||||
peer_id: string
|
||||
peer_name: string
|
||||
known_users: string[]
|
||||
}
|
||||
|
||||
const userPeers: Map<string, Set<string>> = new Map();
|
||||
const peerSockets: Map<string, WebSocket> = new Map();
|
||||
const socketPeers: Map<WebSocket, string> = new Map();
|
||||
|
||||
function helloHandler(m: HelloMessage, socket: WebSocket) {
|
||||
console.log(`Received hello from peer ${colorID(m.peer_id)}:${m.peer_name}, user ${colorID(m.user_id)}:${m.user_name}`);
|
||||
|
||||
|
||||
if (!userPeers.has(m.user_id)) {
|
||||
userPeers.set(m.user_id, new Set());
|
||||
}
|
||||
userPeers.get(m.user_id)?.add(m.peer_id);
|
||||
peerSockets.set(m.peer_id, socket);
|
||||
socketPeers.set(socket, m.peer_id);
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
let returnValue: any = {};
|
||||
for (let key of userPeers.keys()) {
|
||||
let peers = userPeers.get(key);
|
||||
if (!peers) {
|
||||
continue;
|
||||
}
|
||||
returnValue[key] = [...peers.keys()];
|
||||
}
|
||||
|
||||
|
||||
// console.log(returnValue);
|
||||
|
||||
return JSON.stringify({ type: 'hello', userPeers: returnValue });
|
||||
}
|
||||
|
||||
interface InnerMessage {
|
||||
type: string
|
||||
user_id: string
|
||||
}
|
||||
|
||||
interface PeerMessage {
|
||||
type: string
|
||||
from: string
|
||||
from_username: string
|
||||
from_peername: string
|
||||
to: string
|
||||
message: InnerMessage
|
||||
}
|
||||
|
||||
function peerMessageHandler(m: PeerMessage, _socket: WebSocket) {
|
||||
|
||||
console.log(`Peer message type ${m.message.type} from ${colorID(m.from)}:${m.from_peername}:${m.from_username} to ${colorID(m.to)}`)
|
||||
|
||||
let toPeer = peerSockets.get(m.to);
|
||||
if (!toPeer) {
|
||||
console.log(`Couln't find peer ${m.to}`)
|
||||
return null;
|
||||
}
|
||||
|
||||
if (toPeer.readyState !== WebSocket.OPEN) {
|
||||
console.log("Peer socket is not open:", toPeer);
|
||||
return null;
|
||||
}
|
||||
|
||||
let messageToSend = JSON.stringify(m);
|
||||
// console.log("ws->", toPeer, messageToSend);
|
||||
toPeer.send(messageToSend)
|
||||
return null;
|
||||
}
|
||||
|
||||
const messageDispatch: Map<string, (m: any, socket: WebSocket) => string | null> = new Map();
|
||||
|
||||
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("message", (event) => {
|
||||
// console.log(event);
|
||||
let message: any;
|
||||
try {
|
||||
message = JSON.parse(event.data);
|
||||
} catch (e) {
|
||||
console.error("socket.message: ", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
const dispatchHandler = messageDispatch.get(message?.type)
|
||||
if (!dispatchHandler) {
|
||||
console.log("Got message I don't understand: ", event.data);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const response = dispatchHandler(message, socket);
|
||||
// console.log(response);
|
||||
if (response) {
|
||||
socket.send(response);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
socket.addEventListener("close", (event) => {
|
||||
|
||||
});
|
||||
|
||||
return response;
|
||||
|
||||
}
|
||||
|
||||
function handler(request: Request, info: any) {
|
||||
|
||||
// console.log(info.remoteAddr);
|
||||
|
||||
const url = new URL(request.url);
|
||||
if (url.pathname === "/") {
|
||||
return serveFile("/static/index.html")
|
||||
}
|
||||
|
||||
if (url.pathname === "/ws") {
|
||||
return connectWebsocket(request);
|
||||
}
|
||||
|
||||
|
||||
if (url.pathname === "/sw.js") {
|
||||
return serveFile("static/sw.js")
|
||||
}
|
||||
|
||||
if (url.pathname === "/robots).txt") {
|
||||
return serveFile("static/robots.txt")
|
||||
}
|
||||
|
||||
if (url.pathname === "/favicon.ico") {
|
||||
return serveFile("static/favicon.ico")
|
||||
}
|
||||
|
||||
|
||||
if (url.pathname.includes("/static/")) {
|
||||
return serveDir(request, { fsRoot: "../" });
|
||||
}
|
||||
|
||||
return serveFile("/static/index.html")
|
||||
}
|
||||
|
||||
function main() {
|
||||
|
||||
messageDispatch.set('ping', pingHandler);
|
||||
messageDispatch.set('hello', helloHandler);
|
||||
messageDispatch.set('peer_message', peerMessageHandler);
|
||||
|
||||
Deno.serve({
|
||||
port: 6789,
|
||||
cert: Deno.readTextFileSync("/etc/letsencrypt/live/ddlion.net/fullchain.pem"),
|
||||
key: Deno.readTextFileSync("/etc/letsencrypt/live/ddlion.net/privkey.pem"),
|
||||
}, handler);
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -251,7 +251,7 @@ class wsConnection {
|
||||
}
|
||||
|
||||
helloResponseHandler(data: any) {
|
||||
|
||||
debugger
|
||||
let users = [];
|
||||
try {
|
||||
let currentUserPeers = data.userPeers[app.router.userID];
|
||||
@@ -265,9 +265,9 @@ class wsConnection {
|
||||
log(`Net: got ${users.length} users from bootstrap peer. ${users.join(',')}`)
|
||||
|
||||
for (let [userID, peerIDs] of users) {
|
||||
this.peers.set(userID, [...Object.keys(peerIDs as any)]);
|
||||
this.peers.set(userID, [...peerIDs]);
|
||||
|
||||
for (let peerID of [...Object.keys(peerIDs as any)]) {
|
||||
for (let peerID of [...peerIDs]) {
|
||||
if (peerID === this.peerID) {
|
||||
continue;
|
||||
}
|
||||
@@ -323,6 +323,7 @@ class wsConnection {
|
||||
// }
|
||||
|
||||
async getPostIdsForUserHandler(data: any) {
|
||||
debugger;
|
||||
let message = data.message;
|
||||
let postIds = await getAllIds(message.user_id) ?? [];
|
||||
if (postIds.length === 0) {
|
||||
@@ -449,7 +450,7 @@ class wsConnection {
|
||||
|
||||
this.websocket.onmessage = (event) => {
|
||||
// log('ws:<-' + event.data.slice(0, 240));
|
||||
|
||||
debugger;
|
||||
let data = JSON.parse(event.data);
|
||||
|
||||
let { type } = data;
|
||||
|
||||
@@ -174,6 +174,7 @@ class wsConnection {
|
||||
this.websocket.send(json);
|
||||
}
|
||||
helloResponseHandler(data) {
|
||||
debugger;
|
||||
let users = [];
|
||||
try {
|
||||
let currentUserPeers = data.userPeers[app.router.userID];
|
||||
@@ -186,8 +187,8 @@ class wsConnection {
|
||||
users = [...users, ...Object.entries(data.userPeers)];
|
||||
log(`Net: got ${users.length} users from bootstrap peer. ${users.join(',')}`);
|
||||
for (let [userID, peerIDs] of users) {
|
||||
this.peers.set(userID, [...Object.keys(peerIDs)]);
|
||||
for (let peerID of [...Object.keys(peerIDs)]) {
|
||||
this.peers.set(userID, [...peerIDs]);
|
||||
for (let peerID of [...peerIDs]) {
|
||||
if (peerID === this.peerID) {
|
||||
continue;
|
||||
}
|
||||
@@ -228,6 +229,7 @@ class wsConnection {
|
||||
// return compressedArrayBuffer;
|
||||
// }
|
||||
async getPostIdsForUserHandler(data) {
|
||||
debugger;
|
||||
let message = data.message;
|
||||
let postIds = await getAllIds(message.user_id) ?? [];
|
||||
if (postIds.length === 0) {
|
||||
@@ -331,6 +333,7 @@ class wsConnection {
|
||||
};
|
||||
this.websocket.onmessage = (event) => {
|
||||
// log('ws:<-' + event.data.slice(0, 240));
|
||||
debugger;
|
||||
let data = JSON.parse(event.data);
|
||||
let { type } = data;
|
||||
let handler = this.messageHandlers.get(type);
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user