import { Client } from "./client.ts";import { EventHandler } from "./eventhandler.ts";import { Packet } from "./packet.ts";import type { WebSocket } from "../deps.ts";import type { HTTPOptions } from "../deps.ts";import { serve, DenoServer, ServerRequest, serveFile, 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; public lastClientId: number = 1000;
constructor() {
this.eventHandler = new EventHandler(); this.handleWs = this.handleWs.bind(this); }
channel(name: string, callback: () => void) :void { this.channelsList[name] = {};
callback(); return; }
connect(req: ServerRequest, callback: () => void){ const { conn, w:bufWriter, r:bufReader, headers } = req; acceptWebSocket({conn, bufWriter, bufReader, headers}) .then(this.handleWs) .catch(err => console.log(err, 'err')) callback(); }
emit(message: string){ Object.values(this.clients).forEach(client => { client.socket.send(JSON.stringify({message})) }) }
async handleWs (socket: WebSocket):Promise<void> {
const client = new Client(socket, this.lastClientId); this.lastClientId = client.id 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': 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); 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 case in testServer'); } } }}