import { Client } from "./client.ts";import { EventHandler } from "./eventhandler.ts";import { Packet } from "./packet.ts";import type { WebSocket } from "./deps.ts";import type { HTTPOptions, HTTPSOptions} from "./deps.ts";import { serve, Server as DenoServer, serveTLS, ServerRequest } from "https://deno.land/std@0.95.0/http/server.ts";import { serveFile } from "./deps.ts";import { acceptWebSocket, isWebSocketCloseEvent } from "./deps.ts";
export class Sono { public server: DenoServer | null = null; public hostname = 'localhost'; public clients: {[key: string]: Client} = {}; public channelsList: {[key: string]: Record<string, Client>} = {'home': {}}; public eventHandler: EventHandler;
constructor() { this.eventHandler = new EventHandler(); this.handleWs = this.handleWs.bind(this); }
listen(port: number): DenoServer { const options: HTTPOptions = {port}; this.server = serve(options); this.awaitRequests(this.server); return this.server; }
channel(name: string, callback: () => void) :void { this.channelsList[name] = {}; callback(); return; }
async awaitRequests(server: DenoServer):Promise<void> { for await(const req of server) { this.handler(req); } }
async handler(req: ServerRequest) { console.log(req, 'request') if (req.method === "GET" && req.url === "/") { const path = `${Deno.cwd()}/webRTC/assets/index.html` const content = await serveFile(req, path); req.respond(content) } else if (req.method === "GET" && req.url === "/ws") { const { conn, w:bufWriter, r:bufReader, headers } = req; acceptWebSocket({conn, bufWriter, bufReader, headers}) .then(this.handleWs) .catch(err => console.log(err, 'err')) } else if (req.url === "/favicon.ico") { } else { const path = `${Deno.cwd()}/webRTC/assets${req.url}`; const content = await serveFile(req, path); req.respond(content) } }
async handleWs (socket: WebSocket):Promise<void> { const client = new Client(socket, Object.keys(this.clients).length); this.clients[client.id] = client; this.channelsList['home'][client.id] = client;
for await(const message of socket){ if (isWebSocketCloseEvent(message) || typeof message !== 'string'){ delete this.channelsList[client.channel][client.id]; delete this.clients[client.id] break; } const data: Packet = JSON.parse(message)
switch(data.protocol) { case 'message': console.log('case message', this.clients) this.eventHandler.handleMessage(data, client, this.channelsList); break; case 'broadcast': this.eventHandler.broadcast(data, client, this.channelsList) break; case 'changeChannel': this.channelsList = this.eventHandler.changeChannel(data, client, this.channelsList); console.log('case channel', this.channelsList); break; case 'directmessage': this.eventHandler.directMessage(data, client, this.clients); break; case 'grab': this.eventHandler.grab(data, client, this.clients, this.channelsList); break; default: console.log('default hit', data) } } }}