UNPKG

barrageapi

Version:

A library for sending data to Barrage, an advanced streaming analytics service from MIOsoft

220 lines (187 loc) 6.65 kB
var Q = require('q'); var W3CWebSocket = require('websocket').w3cwebsocket; var ServerMessage = require("./ServerMessage.js"); var fs = require("fs"); var ca = [fs.readFileSync(__dirname + '/root.pem'), fs.readFileSync(__dirname + '/inter1.pem'),fs.readFileSync(__dirname + '/inter2.pem')]; var log = require("./log.js")(); //process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; // websocket factory that return a class that needs to be instatiated in each case - allow multiple websockets /* WebSocket javascript API var ws = new WebSocket(url); // url format is "ws://www.example.com/socketserver" ws.onopen = function(event) { //do something on connecting to the websocket}; ws.onclose = function(event) { //do something after closing the connection }; ws.onerror = function(event) { // }; ws.onmessage = function(event) { //event.data is a message from the server}; ws.send(JSON.stringify(message)); //send message to server if (ws == true) { //socket is already open }; */ // ------------ internal private methods --------- function connectToSocket() { var self = this; return Q.Promise(function(resolve,reject) { log("Connecting to ",self.url); self.ws = new W3CWebSocket(self.url, null, null, null, null, {tlsOptions: { ca: ca }}); self.ws.onopen = function(event) { log("Socket opened."); resolve("Success"); }; self.ws.onmessage = function(event) { listener(self,JSON.parse(event.data)); }; self.ws.onclose = function(event) { log("Socket closed.", event.code, event.reason); //Reject all outstanding callbacks for (var key in self.callbacks) { if (self.callbacks.hasOwnProperty(key)) { self.callbacks[key].cb.reject("Socket closed."); delete self.callbacks[key]; } } }; self.ws.onerror = function(event) { log("Failed to open a connection."); reject("Failed. This may be because of a failure to open a connection."); //Reject all outstanding callbacks for (var key in self.callbacks) { if (self.callbacks.hasOwnProperty(key)) { self.callbacks[key].cb.reject("Failed. This may be because of a failure to open a connection."); delete self.callbacks[key]; } } }; }); } //generate a new deferred promise and unique ID, add this request event to the callbacks array //attach the ID to the request, send it through the pipe, and return the promise function sendRequest(request) { var self = this; var defer = Q.defer(); //If the socket is not connected, try to connect it and autologin. if (self.ws.readyState !== 1) { // Prevent infinite recursion if (!self.retried) { self.retried = true; return connectToSocket.call(self).then(function () { log("RECONNECTED SOCKET"); //if (self.reconnectObject) { // return sendRequest.call(self, self.reconnectObject).then(function () { // log("REGAINED SESSION!!!"); // ServerMessage.broadcast("reconnect", self.ids); // return sendRequest.call(self,request); // }).catch(function () { // if (self.loginObject) { // return sendRequest.call(self, self.loginObject).then(function () { // log("RELOGGED IN!!!"); // ServerMessage.broadcast("reconnect", self.ids); // return sendRequest.call(self,request); // }); // } // }); //} /*else*/ if (self.loginObject) { return sendRequest.call(self, self.loginObject).then(function () { log("RELOGGED IN!!!"); ServerMessage.broadcast("reconnect", self.ids); return sendRequest.call(self,request); }); } return sendRequest.call(self,request); }).finally(function (err) { self.retried = false; }); } return defer.promise; } var callbackID = getCallbackID(self); self.callbacks[callbackID] = { time: new Date(), cb: defer }; request.callbackID = callbackID; self.ws.send(JSON.stringify(request)); return defer.promise; } //function for creating a new callback ID for requests function getCallbackID(self) { self.currentCallbackId += 1; if (self.currentCallbackId > 10000) { self.currentCallbackId = 1; } return self.currentCallbackId; } //listener function for processing events/messages from the server function listener(self,data) { var messageObj = data; //if object has a callback_id - resolve the promise by broadcasting though $rootScope (so all controllers can see it) if (self.callbacks.hasOwnProperty(messageObj.callbackID)) { //server response if (messageObj.callbackID > 0) { self.callbacks[messageObj.callbackID].cb.resolve(messageObj); delete self.callbacks[messageObj.callbackID]; } // Messages originating from the server will have callbackID = 0 if (messageObj.callbackID === 0) { log(messageObj); ServerMessage.broadcast(messageObj.eventName, messageObj.data); } //server unable to process message else if (messageObj.callbackID === -1) { log('Server could not process a message from the client far enough to get a callback ID.'); self.callbacks[messageObj.callbackID].cb.reject(messageObj); delete self.callbacks[messageObj.callbackID]; } else { //nonvalid callbackID means what? //log(messageObj); } } else { //handle messages without callback ids here log(messageObj); } } // ------------- constructor ------------- function WebSocketClass(url, id) { this.url = url; this.ids = [id]; this.currentCallbackId = 0; this.callbacks = {}; this.ws = {}; this.loginObject = {}; } // ------------- class methods - websocket API ------------- WebSocketClass.prototype = { addID : function (newID) { if (this.ids.indexOf(newID) === -1) { this.ids.push(newID); } }, makeRequest: function(message) { var self = this; return sendRequest.call(self,message); }, cancelAllRequests: function () { var self = this; var serviceObject = {service : "cancelService", cancel: Object.keys(self.callbacks).map(function (d) { return +d; })}; return sendRequest.call(self, serviceObject); }, initializeSocket: function() { var self = this; return connectToSocket.call(self); }, closeSocket: function() { this.ws.close(); }, checkSocketConnected: function() { /* readyState: 0 - connection not yet established 1 - connected established and communication possible 2 - connection going through closing handshake 3 - connection closed (or could not be opened) */ return this.ws.readyState === 1; }, }; module.exports = WebSocketClass;