Files
api/app/ws.ts

75 lines
2.0 KiB
TypeScript

import { log } from '@unraid/core';
interface subscription {
total: number
channels: string[]
}
const subscriptions: {
[key: string]: subscription
} = {};
/**
* Return current ws connection count.
*/
export const getWsConectionCount = () => {
return Object.values(subscriptions).filter(subscription => subscription.total >= 1).length;
};
/**
* Return current ws connection count in channel.
*/
export const getWsConectionCountInChannel = (channel: string) => {
return Object.values(subscriptions).filter(subscription => subscription.channels.includes(channel)).length;
};
export const hasSubscribedToChannel = (id: string, channel: string) => {
subscriptions[id].total++;
subscriptions[id].channels.push(channel);
};
export const hasUnsubscribedFromChannel = (id: string, channel: string) => {
subscriptions[id].total--;
subscriptions[id].channels = subscriptions[id].channels.filter(existingChannel => existingChannel !== channel);
};
/**
* Websocket has connected.
*
* @param ws
*/
export const wsHasConnected = (id: string) => {
subscriptions[id] = {
total: 0,
channels: []
};
};
/**
* Websocket has disconnected.
*
* @param ws
*/
export const wsHasDisconnected = (id: string) => {
subscriptions[id].total = 0;
subscriptions[id].channels = [];
};
// Only allows function to publish to pubsub when clients are online and are connected to the specific channel
// the reason we do this is otherwise pubsub will cause a memory leak
export const canPublishToChannel = (channel: string) => {
// No ws connections
if (getWsConectionCount() === 0) {
return false;
}
// No ws connections to this channel
const channelConnectionCount = getWsConectionCountInChannel(channel);
if (channelConnectionCount === 0) {
return false;
}
const plural = channelConnectionCount !== 1;
log.debug(`Allowing publish to "${channel}" as there ${plural ? 'are' : 'is'} ${channelConnectionCount} connection${plural ? 's' : ''} in that channel.`);
return true;
};