Guest User

Untitled

a guest
Oct 18th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.64 KB | None | 0 0
  1. const clients = {};
  2. let wss = null;
  3.  
  4. const delimiter = '_';
  5.  
  6. /**
  7. * Clients are stored as "companyId_deviceId"
  8. */
  9. function getClients() {
  10. return clients;
  11. }
  12.  
  13. function sendMessage(companyId, msg) {
  14. try {
  15. const clientKey = Object.keys(clients).find((a) => a.split(delimiter)[0] === companyId.toString());
  16.  
  17. const socketForUser = clients[clientKey];
  18. if (socketForUser && socketForUser.readyState === WebSocket.OPEN) {
  19. socketForUser.send(JSON.stringify(msg));
  20. } else {
  21. console.info(`WEBSOCKET: could not send message to company ${companyId}`);
  22. }
  23. } catch (ex) {
  24. console.error(`WEBSOCKET: could not send message to company ${companyId}: `, ex);
  25. }
  26. }
  27.  
  28. function noop() { }
  29.  
  30. function heartbeat() {
  31. this.isAlive = true;
  32. }
  33.  
  34. function deleteClient(clientInfo) {
  35. delete clients[`${clientInfo.companyId}${delimiter}${clientInfo.deviceId}`];
  36.  
  37. // notify all clients
  38. forceRefreshAllClients();
  39. }
  40.  
  41. function createSocket(server) {
  42. wss = new WebSocket.Server({ server });
  43.  
  44. wss.on('connection', async (ws, req) => {
  45. try {
  46. // verify socket connection
  47. let { query: { accessToken } } = url.parse(req.url, true);
  48. const decoded = await tokenHelper.decode(accessToken);
  49.  
  50. // add new websocket to clients store
  51. ws.isAlive = true;
  52. clients[`${decoded.companyId}${delimiter}${decoded.deviceId}`] = ws;
  53. console.info(`WEBSOCKET: ➕ Added client for company ${decoded.companyId} and device ${decoded.deviceId}`);
  54.  
  55. await tokenHelper.verify(accessToken);
  56.  
  57. // notify all clients about new client coming up
  58. // including the newly created socket client...
  59. forceRefreshAllClients();
  60.  
  61. ws.on('pong', heartbeat);
  62. } catch (ex) {
  63. console.error('WEBSOCKET: WebSocket Error', ex);
  64. ws.send(JSON.stringify({ type: 'ERROR', data: { status: 401, title: 'invalid token' } }));
  65. }
  66.  
  67. ws.on('close', async () => {
  68. const location = url.parse(req.url, true);
  69. const decoded = await tokenHelper.decode(location.query.accessToken);
  70.  
  71. deleteClient({ companyId: decoded.companyId, deviceId: decoded.deviceId });
  72. });
  73. });
  74.  
  75. // Ping pong on interval will remove the client if the client has no internet connection
  76. setInterval(() => {
  77. Object.keys(clients).forEach((clientKey) => {
  78. const ws = clients[clientKey];
  79. if (ws.isAlive === false) return ws.terminate();
  80.  
  81. ws.isAlive = false;
  82. ws.ping(noop);
  83. });
  84. }, 15000);
  85. }
  86.  
  87. function forceRefreshAllClients() {
  88. setTimeout(function () {
  89. Object.keys(clients).forEach((key) => {
  90. const companyId = key.split(delimiter)[0];
  91. sendMessage(companyId, createForcedRefreshMessage());
  92. });
  93. }, 1000);
  94. }
Add Comment
Please, Sign In to add comment