Files
UDN/websocket-handler.ts
T

97 lines
2.6 KiB
TypeScript
Raw Normal View History

2024-07-04 17:27:38 +02:00
// TYPES
2024-07-05 00:15:00 +02:00
import { SubscriptionMap } from "./subscriptionMap";
2024-07-04 17:27:46 +02:00
import { WS } from "./index";
2024-07-05 00:15:00 +02:00
import { guardStringNotEmpty } from "./utility";
2024-07-04 17:27:46 +02:00
// requests
export interface IncomingMessage {
2024-07-04 17:27:38 +02:00
// subscribing to channel
2024-07-04 17:27:46 +02:00
subscribeChannel?: string;
unsubscribeChannel?: string;
2024-07-04 17:27:38 +02:00
//sending message
messageChannel?: string;
messageBody?: string;
}
2024-07-04 17:27:46 +02:00
// TRACKING
2024-07-05 12:48:42 +02:00
export const subscriptions = new SubscriptionMap();
export let connectionCount = 0;
export function addConnection() {
connectionCount++;
}
2024-07-04 17:27:46 +02:00
export function trackSubscription(ws: WS, channel: string): void {
subscriptions.set(ws, channel);
confirmSubscription(ws, channel);
2024-07-04 17:27:38 +02:00
}
2024-07-04 17:27:46 +02:00
export function removeSubscription(ws: WS, channel: string): void {
subscriptions.delete(ws, channel);
confirmSubscription(ws, channel);
}
2024-07-04 17:27:38 +02:00
2024-07-04 17:27:46 +02:00
export function forgetConnection(ws: WS): void {
2024-07-05 12:48:42 +02:00
connectionCount--;
2024-07-04 17:27:46 +02:00
const channels = subscriptions.getChannelList(ws);
channels?.forEach((channel) => {
subscriptions.delete(ws, channel);
});
}
2024-07-05 12:48:42 +02:00
// AUDIT
export function audit(): [string, number][] {
return [
["channels", subscriptions.clientsPerChannel.size],
["users connected", connectionCount],
["users susbcribing", subscriptions.channelsPerClient.size],
];
}
2024-07-04 17:27:46 +02:00
// PROCESS MESSAGE
export function processMessage(ws: WS, messageString: string): void {
const messageObject: IncomingMessage = parseMessage(messageString);
2024-07-05 00:15:00 +02:00
guardStringNotEmpty(messageObject.subscribeChannel, (subscribeChannel) => {
trackSubscription(ws, subscribeChannel);
});
2024-07-05 00:17:24 +02:00
guardStringNotEmpty(
messageObject.unsubscribeChannel,
(unsubscribeChannel) => {
removeSubscription(ws, unsubscribeChannel);
}
);
2024-07-05 12:48:42 +02:00
guardStringNotEmpty(messageObject.messageChannel, (messageChannel) => {
if (!messageObject.messageBody) return;
sendMessage(messageChannel, messageObject.messageBody);
});
2024-07-04 17:27:46 +02:00
}
// MESSAGING
export function stringifyMessage(messageObject: Object): string {
return JSON.stringify(messageObject);
}
2024-07-04 17:27:38 +02:00
2024-07-04 17:27:46 +02:00
export function parseMessage(messageString: string): Object {
return JSON.parse(messageString);
2024-07-04 17:27:38 +02:00
}
2024-07-04 17:27:46 +02:00
export function sendMessage(channel: string, body: string): void {
const messageObject = { channel, body };
const messageString = stringifyMessage(messageObject);
2024-07-04 17:27:38 +02:00
2024-07-04 17:27:46 +02:00
const subscribers = subscriptions.getClientList(channel);
subscribers?.forEach((ws) => ws.send(messageString));
2024-07-04 17:27:38 +02:00
}
2024-07-04 17:27:46 +02:00
function confirmSubscription(ws: WS, channel: string): void {
const messageObject = {
channel: channel,
2024-07-05 00:17:24 +02:00
subscribed: subscriptions.getChannelList(ws) ? true : false,
2024-07-04 17:27:46 +02:00
};
const messageString = stringifyMessage(messageObject);
ws.send(messageString);
2024-07-04 17:27:38 +02:00
}