UNPKG

socio

Version:

A WebSocket Real-Time Communication (RTC) API framework.

87 lines (86 loc) 3.15 kB
import { E } from "./logging.js"; export class ServerChatRoom { static #room_ids = new Set(); static #id_counter = 0; #room_id; #users = new Set(); #messages = new Set(); history_length; server_interface; constructor(ServerSendToClients, message_history_length = 10) { const room_id = ++ServerChatRoom.#id_counter; ServerChatRoom.#room_ids.add(room_id); this.#room_id = room_id; this.history_length = message_history_length; this.server_interface = ServerSendToClients; } CloseRoom() { ServerChatRoom.#room_ids.delete(this.#room_id); } get room_id() { return this.#room_id; } static get room_ids() { return ServerChatRoom.#room_ids; } Join(client_id) { this.#users.add({ client_id }); this.server_interface([client_id], { rel: 'SocioChatRoom', type: 'msg_history', msgs: this.#messages }); } Leave(client_id) { this.#users.delete({ client_id }); } Post(client_id, text) { const new_message = { user: { client_id }, ts: (new Date()).getTime(), text }; this.#messages.add(new_message); if (this.#messages.size > this.history_length) this.#messages.delete(this.#messages.values().next().value); const clients = [...this.#users.values()].map(c => c.client_id); this.server_interface(clients, { rel: 'SocioChatRoom', type: 'new_msg', msgs: new Set([new_message]) }); } } export class ChatRoomClient { #current_room_id = 0; serv; msg_hook; constructor(ClientSendToServer, msg_hook) { this.serv = ClientSendToServer; this.msg_hook = msg_hook; } Join(room_id) { this.serv({ rel: 'SocioChatRoom', type: 'join', room_id }); this.#current_room_id = room_id; } Leave() { this.serv({ rel: 'SocioChatRoom', type: 'leave', room_id: this.#current_room_id }); } Post(text) { this.serv({ rel: 'SocioChatRoom', type: 'new_msg', text, room_id: this.#current_room_id }); } Receive(msgs) { this.msg_hook(msgs); } } export function HandleChatRoomServ(client, data, chat_rooms) { if (data?.data?.rel == 'SocioChatRoom') { const chat = chat_rooms.find(c => c.room_id === data.data?.room_id); if (!chat) return; switch (data.data?.type) { case 'join': { chat.Join(client.id); break; } case 'leave': { chat.Leave(client.id); break; } case 'new_msg': { chat.Post(client.id, data.data?.text); break; } default: throw new E('Unknown SocioChatRoom SERV msg type!'); } } } export function HandleChatRoomCMD(data, chat) { if (data?.rel == 'SocioChatRoom') { switch (data?.type) { case 'msg_history': { chat.Receive(data?.msgs); break; } case 'new_msg': { chat.Receive(data?.msgs); break; } default: throw new E('Unknown SocioChatRoom CMD msg type!'); } } }