var RpcBuilder = require('../'); var WebSocketWithReconnection = require('./transports/webSocketWithReconnection'); Date.now = Date.now || function () { return +new Date; }; var PING_INTERVAL = 5000; var RECONNECTING = 'RECONNECTING'; var CONNECTED = 'CONNECTED'; var DISCONNECTED = 'DISCONNECTED'; var Logger = console; function JsonRpcClient(configuration) { var self = this; var wsConfig = configuration.ws; var notReconnectIfNumLessThan = -1; var pingNextNum = 0; var enabledPings = true; var pingPongStarted = false; var pingInterval; var status = DISCONNECTED; var onreconnecting = wsConfig.onreconnecting; var onreconnected = wsConfig.onreconnected; var onconnected = wsConfig.onconnected; var onerror = wsConfig.onerror; configuration.rpc.pull = function (params, request) { request.reply(null, "push"); }; wsConfig.onreconnecting = function () { Logger.debug("--------- ONRECONNECTING -----------"); if (status === RECONNECTING) { Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); return; } status = RECONNECTING; if (onreconnecting) { onreconnecting(); } }; wsConfig.onreconnected = function () { Logger.debug("--------- ONRECONNECTED -----------"); if (status === CONNECTED) { Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it"); return; } status = CONNECTED; enabledPings = true; updateNotReconnectIfLessThan(); usePing(); if (onreconnected) { onreconnected(); } }; wsConfig.onconnected = function () { Logger.debug("--------- ONCONNECTED -----------"); if (status === CONNECTED) { Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it"); return; } status = CONNECTED; enabledPings = true; usePing(); if (onconnected) { onconnected(); } }; wsConfig.onerror = function (error) { Logger.debug("--------- ONERROR -----------"); status = DISCONNECTED; if (onerror) { onerror(error); } }; var ws = new WebSocketWithReconnection(wsConfig); Logger.debug('Connecting websocket to URI: ' + wsConfig.uri); var rpcBuilderOptions = { request_timeout: configuration.rpc.requestTimeout, ping_request_timeout: configuration.rpc.heartbeatRequestTimeout }; var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) { Logger.debug('Received request: ' + JSON.stringify(request)); try { var func = configuration.rpc[request.method]; if (func === undefined) { Logger.error("Method " + request.method + " not registered in client"); } else { func(request.params, request); } } catch (err) { Logger.error('Exception processing request: ' + JSON.stringify(request)); Logger.error(err); } }); this.send = function (method, params, callback) { if (method !== 'ping') { Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params)); } var requestTime = Date.now(); rpc.encode(method, params, function (error, result) { if (error) { try { Logger.error("ERROR:" + error.message + " in Request: method:" + method + " params:" + JSON.stringify(params) + " request:" + error.request); if (error.data) { Logger.error("ERROR DATA:" + JSON.stringify(error.data)); } } catch (e) { } error.requestTime = requestTime; } if (callback) { if (result != undefined && result.value !== 'pong') { Logger.debug('Response: ' + JSON.stringify(result)); } callback(error, result); } }); }; function updateNotReconnectIfLessThan() { Logger.debug("notReconnectIfNumLessThan = " + pingNextNum + ' (old=' + notReconnectIfNumLessThan + ')'); notReconnectIfNumLessThan = pingNextNum; } function sendPing() { if (enabledPings) { var params = null; if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) { params = { interval: configuration.heartbeat || PING_INTERVAL }; } pingNextNum++; self.send('ping', params, (function (pingNum) { return function (error, result) { if (error) { Logger.debug("Error in ping request #" + pingNum + " (" + error.message + ")"); if (pingNum > notReconnectIfNumLessThan) { enabledPings = false; updateNotReconnectIfLessThan(); Logger.debug("Server did not respond to ping message #" + pingNum + ". Reconnecting... "); ws.reconnectWs(); } } }; })(pingNextNum)); } else { Logger.debug("Trying to send ping, but ping is not enabled"); } } function usePing() { if (!pingPongStarted) { Logger.debug("Starting ping (if configured)"); pingPongStarted = true; if (configuration.heartbeat != undefined) { pingInterval = setInterval(sendPing, configuration.heartbeat); sendPing(); } } } this.close = function () { Logger.debug("Closing jsonRpcClient explicitly by client"); if (pingInterval != undefined) { Logger.debug("Clearing ping interval"); clearInterval(pingInterval); } pingPongStarted = false; enabledPings = false; if (configuration.sendCloseMessage) { Logger.debug("Sending close message"); this.send('closeSession', null, function (error, result) { if (error) { Logger.error("Error sending close message: " + JSON.stringify(error)); } ws.close(); }); } else { ws.close(); } }; this.forceClose = function (millis) { ws.forceClose(millis); }; this.reconnect = function () { ws.reconnectWs(); }; } module.exports = JsonRpcClient; //# sourceMappingURL=jsonrpcclient.js.map