Skip to content

Commit

Permalink
Merge pull request #10 from rainmattertech/autoreconnect
Browse files Browse the repository at this point in the history
Autoreconnect for WebSocket client
  • Loading branch information
vividvilla authored Mar 12, 2017
2 parents 815c001 + f0613ac commit 9f7ea5b
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 14 deletions.
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,57 @@ Getting started WebSocket client
ticker.setMode(ticker.modeFull, items);
}

Auto re-connect WebSocket client
-------------------------------
```
Available from version 1.2
```
Optionally you can enable client side auto reconnection to automatically reconnect if the connection is dropped.
It is very useful at times when client side network is unreliable and patchy.

All you need to do is enable auto reconnection with preferred interval and time. For example

// Enable auto reconnect with 5 second interval and retry for maximum of 20 times.
ticker.autoReconnect(true, 20, 5)

// You can also set reconnection times to -1 for inifinite reconnections
ticker.autoReconnect(true, -1, 5)

- Event `reconnecting` is called when auto reconnection is triggered and event callback carries two additional params `reconnection interval set` and `current reconnection count`.

- Event `noreconnect` is called when number of auto reconnections exceeds the maximum reconnection count set. For example if maximum reconnection count is set as `20` then after 20th reconnection this event will be triggered. Also note that the current process is exited when this event is triggered.

- Event `connect` will be triggered again when reconnection succeeds.

Here is an example demonstrating auto reconnection.

var KiteTicker = require("kiteconnect").KiteTicker;
var ticker = new KiteTicker(api_key, user_id, public_token);

// set autoreconnect with 10 maximum reconnections and 5 second interval
ticker.autoReconnect(true, 10, 5)
ticker.connect();
ticker.on("tick", setTick);
ticker.on("connect", subscribe);

ticker.on("noreconnect", function() {
console.log("noreconnect")
});

ticker.on("reconnecting", function(reconnect_interval, reconnections) {
console.log("Reconnecting: attempet - ", reconnections, " innterval - ", reconnect_interval);
});

function setTick(ticks) {
console.log("Ticks", ticks);
}

function subscribe() {
var items = [738561];
ticker.subscribe(items);
ticker.setMode(ticker.modeFull, items);
}

A typical web application
-------------------------
In a typical web application where a new instance of
Expand Down
108 changes: 95 additions & 13 deletions lib/ticker.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,57 @@ var WebSocket = require("ws");
* }]
* }
* }, ...]
*
Auto re-connect WebSocket client
-------------------------------
```
Available from version 1.2
```
Optionally you can enable client side auto reconnection to automatically reconnect if the connection is dropped.
It is very useful at times when client side network is unreliable and patchy.
All you need to do is enable auto reconnection with preferred interval and time. For example
// Enable auto reconnect with 5 second interval and retry for maximum of 20 times.
ticker.autoReconnect(true, 20, 5)
// You can also set reconnection times to -1 for inifinite reconnections
ticker.autoReconnect(true, -1, 5)
- Event `reconnecting` is called when auto reconnection is triggered and event callback carries two additional params `reconnection interval set` and `current reconnection count`.
- Event `noreconnect` is called when number of auto reconnections exceeds the maximum reconnection count set. For example if maximum reconnection count is set as `20` then after 20th reconnection this event will be triggered. Also note that the current process is exited when this event is triggered.
- Event `connect` will be triggered again when reconnection succeeds.
Here is an example demonstrating auto reconnection.
var KiteTicker = require("kiteconnect").KiteTicker;
var ticker = new KiteTicker(api_key, user_id, public_token);
// set autoreconnect with 10 maximum reconnections and 5 second interval
ticker.autoReconnect(true, 10, 5)
ticker.connect();
ticker.on("tick", setTick);
ticker.on("connect", subscribe);
ticker.on("noreconnect", function() {
console.log("noreconnect")
});
ticker.on("reconnecting", function(reconnect_interval, reconnections) {
console.log("Reconnecting: attempet - ", reconnections, " innterval - ", reconnect_interval);
});
function setTick(ticks) {
console.log("Ticks", ticks);
}
function subscribe() {
var items = [738561];
ticker.subscribe(items);
ticker.setMode(ticker.modeFull, items);
}
*
* @constructor
* @name KiteTicker
Expand Down Expand Up @@ -124,7 +174,7 @@ var KiteTicker = function(api_key, user_id, public_token, address) {
mClearCache = 14,

// public constants
modeFull = "full", // Full quote inluding market depth. 164 bytes.
modeFull = "full", // Full quote including market depth. 164 bytes.
modeQuote = "quote", // Quote excluding market depth. 52 bytes.
modeLTP = "ltp";

Expand Down Expand Up @@ -159,7 +209,7 @@ var KiteTicker = function(api_key, user_id, public_token, address) {
reconnect_timer = null,
auto_reconnect = false,
reconnections = 0,
id = null,
currentWsUrl = null,
token_modes = {};

// segment constants
Expand All @@ -175,17 +225,22 @@ var KiteTicker = function(api_key, user_id, public_token, address) {

/**
* Auto reconnect settings
* @param {bool} Enable or disable auto disconnect.
* @param {number} [times=5] Number of times to retry.
* @param {bool} Enable or disable auto disconnect, defaults to false
* @param {number} [times=5] Number of times to retry, defaults to 5. Set -1 for infinite reconnections.
* @param {number} [times=5] Timeout in seconds, default to 5.
* @memberOf KiteTicker
* @method autoReconnect
*/
this.autoReconnect = function(t, times) {
this.autoReconnect = function(t, times, timeout) {
auto_reconnect = (t == true ? true : false);

if(times) {
reconnect_tries = times;
}

if(timeout) {
reconnect_interval = timeout;
}
};

/**
Expand All @@ -199,10 +254,20 @@ var KiteTicker = function(api_key, user_id, public_token, address) {
return;
}

ws = new WebSocket(address + "?api_key=" + api_key + "&user_id=" + user_id + "&public_token=" + public_token);
ws = new WebSocket(address + "?api_key=" + api_key + "&user_id=" + user_id +
"&public_token=" + public_token + "&uid=" + (new Date().getTime().toString()));
ws.binaryType = "arraybuffer";

ws.onopen = function() {
// Store current open connection url to check for auto reconnection
if (!currentWsUrl) {
currentWsUrl = this.url
}

// Reset reconnections attempt
reconnections = 0

// Trigger onconnect event
trigger("connect");

// If there isn't an incoming message in n seconds, assume disconnection.
Expand All @@ -211,7 +276,11 @@ var KiteTicker = function(api_key, user_id, public_token, address) {
last_read = new Date();
read_timer = setInterval(function() {
if((new Date() - last_read ) / 1000 >= read_timeout) {
id = null;
// reset currentWsUrl incase current connection times out
// This is determined when last heart beat received time interval
// exceeds read_timeout value
currentWsUrl = null;

if(ws) {
ws.close();
}
Expand All @@ -233,14 +302,23 @@ var KiteTicker = function(api_key, user_id, public_token, address) {
}
}

// Set last read time to check for connection timeout
last_read = new Date();
};

ws.onerror = function(e) {
ws.close();
if(this && this.readyState == this.OPEN) {
this.close();
}
};

ws.onclose = function(e) {
// the ws id doesn't match the current global id,
// meaning it's a ghost close event. just ignore.
if(currentWsUrl && (this.url != currentWsUrl)) {
return;
}

triggerDisconnect();
};
};
Expand Down Expand Up @@ -278,7 +356,7 @@ var KiteTicker = function(api_key, user_id, public_token, address) {
* connect - when connection is successfully established.
* tick - when ticks are available (Arrays of `ticks` object as the first argument).
* disconnect - when socket connction is disconnected.
* reconnecting - When reconnecting (Reconnecting interval as first argument).
* reconnecting - When reconnecting (Reconnecting interval and current reconnetion count as arguments respectively).
* noreconnect - When reconnection fails after n number times.
* ~~~~
*
Expand Down Expand Up @@ -358,6 +436,10 @@ var KiteTicker = function(api_key, user_id, public_token, address) {
function triggerDisconnect() {
ws = null;
trigger("disconnect");

if(auto_reconnect) {
attemptReconnection();
}
}

// send a message via the socket
Expand Down Expand Up @@ -501,12 +583,12 @@ var KiteTicker = function(api_key, user_id, public_token, address) {

function attemptReconnection() {
// Try reconnecting only so many times.
if(reconnections > reconnect_tries) {
if(reconnect_tries !== -1 && reconnections >= reconnect_tries) {
trigger("noreconnect");
return;
process.exit(1);
}

trigger("reconnecting", [reconnect_interval]);
trigger("reconnecting", [reconnect_interval, reconnections]);
reconnect_timer = setTimeout(function() {
self.connect();
}, reconnect_interval * 1000);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kiteconnect",
"version": "1.1.1",
"version": "1.2",
"description": "The official JS client library for the Kite Connect trading APIs",
"main": "./lib/",
"scripts": {
Expand Down

0 comments on commit 9f7ea5b

Please sign in to comment.