add channel communication

This commit is contained in:
marlonerler
2024-07-04 17:27:46 +02:00
parent 2770d9b07d
commit 9649e3e522
5 changed files with 239 additions and 56 deletions
+61 -26
View File
@@ -1,42 +1,77 @@
// TYPES
// requests
interface IncomingMessage {
//sent on new connections
connectionType?: ConnectionType;
import { SubscriptionMap } from "./auxilary";
import { WS } from "./index";
// requests
export interface IncomingMessage {
// subscribing to channel
channelSubscription?: string;
subscribeChannel?: string;
unsubscribeChannel?: string;
//sending message
messageChannel?: string;
messageBody?: string;
}
// connections
enum ConnectionType {
Server = "server",
Client = "client",
}
// TRACKING
const serversOnEntireNetwork = new Set<WebSocket>();
const subscriptions = new SubscriptionMap();
const socketsPerChannel = new Map<string, Set<WebSocket>>();
const channelsPerSocket = new Map<WebSocket, Set<string>>();
export function trackServer(ws: WebSocket): void {
serversOnEntireNetwork.add(ws);
export function trackSubscription(ws: WS, channel: string): void {
subscriptions.set(ws, channel);
confirmSubscription(ws, channel);
}
export function trackSubscription(channel: string, ws: WebSocket): void {
if (!socketsPerChannel.has(channel)) socketsPerChannel.set(channel, new Set());
if (!channelsPerSocket.has(ws)) channelsPerSocket.set(ws, new Set());
socketsPerChannel.get(channel)!.add(ws);
channelsPerSocket.get(ws)!.add(channel);
export function removeSubscription(ws: WS, channel: string): void {
subscriptions.delete(ws, channel);
confirmSubscription(ws, channel);
}
export function forgetConnection(ws: WebSocket): void {
serversOnEntireNetwork.delete(ws);
serversOnEntireNetwork.delete(ws);
export function forgetConnection(ws: WS): void {
const channels = subscriptions.getChannelList(ws);
channels?.forEach((channel) => {
subscriptions.delete(ws, channel);
});
}
// PROCESS MESSAGE
export function processMessage(ws: WS, messageString: string): void {
const messageObject: IncomingMessage = parseMessage(messageString);
if (typeof messageObject.subscribeChannel == "string") {
trackSubscription(ws, messageObject.subscribeChannel);
} else if (typeof messageObject.unsubscribeChannel == "string") {
removeSubscription(ws, messageObject.unsubscribeChannel);
} else if (
typeof messageObject.messageChannel == "string" &&
typeof messageObject.messageBody == "string"
) {
sendMessage(messageObject.messageChannel, messageObject.messageBody);
}
}
// MESSAGING
export function stringifyMessage(messageObject: Object): string {
return JSON.stringify(messageObject);
}
export function parseMessage(messageString: string): Object {
return JSON.parse(messageString);
}
export function sendMessage(channel: string, body: string): void {
const messageObject = { channel, body };
const messageString = stringifyMessage(messageObject);
const subscribers = subscriptions.getClientList(channel);
subscribers?.forEach((ws) => ws.send(messageString));
}
function confirmSubscription(ws: WS, channel: string): void {
const messageObject = {
channel: channel,
subscribed: subscriptions.getChannelList(ws)?.has(channel),
};
const messageString = stringifyMessage(messageObject);
ws.send(messageString);
}