]> git.r.bdr.sh - rbdr/forum/blobdiff - app/socket_coordinator.js
Add retries to socket coordinator
[rbdr/forum] / app / socket_coordinator.js
index d6768acb1943d5703d28103b8a7525a22fbdb6e6..f8fb52512a806db7c99e8a6e62ba01e04c9df365 100644 (file)
@@ -1,12 +1,52 @@
+import EventEmitter from 'eventemitter3';
 import { socketServer } from './config/config';
 
 const internals = {
 
+  kReconnectInterval: 3000, // How often we attempt to reconnect
+
+  eventEmitter: new EventEmitter(), // internal event emitter
   socket: null, // stores the socket connection
+  retry: null, // stores the retry operation
 
   connect() {
 
+    console.debug('Connecting socket.');
     internals.socket = new WebSocket(socketServer);
+
+    internals.socket.addEventListener('message', internals.onMessage);
+    internals.socket.addEventListener('error', internals.onError);
+    internals.socket.addEventListener('close', internals.onClose);
+  },
+
+  // Handles socket errors.
+
+  onError(event) {
+
+    console.error('Socket error. Closing connection');
+    internals.socket.close();
+  },
+
+  // Handles socket errors.
+
+  onClose(event) {
+
+    console.debug(`Connection closed: ${event.reason || 'Unknown reason'}. Retrying in ${internals.kReconnectInterval}ms`);
+
+    internals.retry && clearTimeout(internals.retry);
+    internals.retry = setTimeout(() => {
+
+      console.debug('Reconnecting socket.');
+      internals.retry = null;
+      internals.connect();
+    }, internals.kReconnectInterval);
+  },
+
+  // Forwards events from the socket to our internal event emitter.
+
+  onMessage(event)  {
+
+    internals.eventEmitter.emit('message', event);
   }
 };
 
@@ -16,7 +56,7 @@ export const onMessage = function (listener) {
     internals.connect();
   }
 
-  internals.socket.addEventListener('message', (message) => {
+  internals.eventEmitter.on('message', (message) => {
 
     listener(JSON.parse(message.data));
   });