Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const clients = {};
- let wss = null;
- const delimiter = '_';
- /**
- * Clients are stored as "companyId_deviceId"
- */
- function getClients() {
- return clients;
- }
- function sendMessage(companyId, msg) {
- try {
- const clientKey = Object.keys(clients).find((a) => a.split(delimiter)[0] === companyId.toString());
- const socketForUser = clients[clientKey];
- if (socketForUser && socketForUser.readyState === WebSocket.OPEN) {
- socketForUser.send(JSON.stringify(msg));
- } else {
- console.info(`WEBSOCKET: could not send message to company ${companyId}`);
- }
- } catch (ex) {
- console.error(`WEBSOCKET: could not send message to company ${companyId}: `, ex);
- }
- }
- function noop() { }
- function heartbeat() {
- this.isAlive = true;
- }
- function deleteClient(clientInfo) {
- delete clients[`${clientInfo.companyId}${delimiter}${clientInfo.deviceId}`];
- // notify all clients
- forceRefreshAllClients();
- }
- function createSocket(server) {
- wss = new WebSocket.Server({ server });
- wss.on('connection', async (ws, req) => {
- try {
- // verify socket connection
- let { query: { accessToken } } = url.parse(req.url, true);
- const decoded = await tokenHelper.decode(accessToken);
- // add new websocket to clients store
- ws.isAlive = true;
- clients[`${decoded.companyId}${delimiter}${decoded.deviceId}`] = ws;
- console.info(`WEBSOCKET: ➕ Added client for company ${decoded.companyId} and device ${decoded.deviceId}`);
- await tokenHelper.verify(accessToken);
- // notify all clients about new client coming up
- // including the newly created socket client...
- forceRefreshAllClients();
- ws.on('pong', heartbeat);
- } catch (ex) {
- console.error('WEBSOCKET: WebSocket Error', ex);
- ws.send(JSON.stringify({ type: 'ERROR', data: { status: 401, title: 'invalid token' } }));
- }
- ws.on('close', async () => {
- const location = url.parse(req.url, true);
- const decoded = await tokenHelper.decode(location.query.accessToken);
- deleteClient({ companyId: decoded.companyId, deviceId: decoded.deviceId });
- });
- });
- // Ping pong on interval will remove the client if the client has no internet connection
- setInterval(() => {
- Object.keys(clients).forEach((clientKey) => {
- const ws = clients[clientKey];
- if (ws.isAlive === false) return ws.terminate();
- ws.isAlive = false;
- ws.ping(noop);
- });
- }, 15000);
- }
- function forceRefreshAllClients() {
- setTimeout(function () {
- Object.keys(clients).forEach((key) => {
- const companyId = key.split(delimiter)[0];
- sendMessage(companyId, createForcedRefreshMessage());
- });
- }, 1000);
- }
Add Comment
Please, Sign In to add comment