implemented timeout over websocket connection
This commit is contained in:
parent
76495e674d
commit
913f36043a
|
@ -51,6 +51,6 @@
|
||||||
"jsonwebtoken": "^7.1.9",
|
"jsonwebtoken": "^7.1.9",
|
||||||
"sni": "^1.0.0",
|
"sni": "^1.0.0",
|
||||||
"tunnel-packer": "^1.1.0",
|
"tunnel-packer": "^1.1.0",
|
||||||
"ws": "^1.1.1"
|
"ws": "^2.2.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
66
wsclient.js
66
wsclient.js
|
@ -7,6 +7,9 @@ var Packer = require('tunnel-packer');
|
||||||
|
|
||||||
function run(copts) {
|
function run(copts) {
|
||||||
var tunnelUrl = copts.stunneld.replace(/\/$/, '') + '/?access_token=' + copts.token;
|
var tunnelUrl = copts.stunneld.replace(/\/$/, '') + '/?access_token=' + copts.token;
|
||||||
|
var activityTimeout = copts.activityTimeout || 2*60*1000;
|
||||||
|
var pongTimeout = copts.pongTimeout || 10*1000;
|
||||||
|
|
||||||
var wstunneler;
|
var wstunneler;
|
||||||
var authenticated = false;
|
var authenticated = false;
|
||||||
|
|
||||||
|
@ -164,23 +167,65 @@ function run(copts) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var retry = true;
|
var retry = true;
|
||||||
var retryTimeout;
|
var lastActivity;
|
||||||
|
var timeoutId;
|
||||||
var wsHandlers = {
|
var wsHandlers = {
|
||||||
onOpen: function () {
|
refreshTimeout: function () {
|
||||||
|
lastActivity = Date.now();
|
||||||
|
}
|
||||||
|
, checkTimeout: function () {
|
||||||
|
if (!wstunneler) {
|
||||||
|
console.warn('checkTimeout called when websocket already closed');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Determine how long the connection has been "silent", ie no activity.
|
||||||
|
var silent = Date.now() - lastActivity;
|
||||||
|
|
||||||
|
// If we have had activity within the last activityTimeout then all we need to do is
|
||||||
|
// call this function again at the soonest time when the connection could be timed out.
|
||||||
|
if (silent < activityTimeout) {
|
||||||
|
timeoutId = setTimeout(wsHandlers.checkTimeout, activityTimeout-silent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise we check to see if the pong has also timed out, and if not we send a ping
|
||||||
|
// and call this function again when the pong will have timed out.
|
||||||
|
else if (silent < activityTimeout + pongTimeout) {
|
||||||
|
console.log('pinging tunnel server');
|
||||||
|
try {
|
||||||
|
wstunneler.ping();
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('failed to ping tunnel server', err);
|
||||||
|
}
|
||||||
|
timeoutId = setTimeout(wsHandlers.checkTimeout, pongTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last case means the ping we sent before didn't get a response soon enough, so we
|
||||||
|
// need to close the websocket connection.
|
||||||
|
else {
|
||||||
|
console.log('connection timed out');
|
||||||
|
wstunneler.close(1000, 'connection timeout');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
, onOpen: function () {
|
||||||
console.info("[open] connected to '" + copts.stunneld + "'");
|
console.info("[open] connected to '" + copts.stunneld + "'");
|
||||||
|
wsHandlers.refreshTimeout();
|
||||||
|
timeoutId = setTimeout(wsHandlers.checkTimeout, activityTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
, onClose: function () {
|
, onClose: function () {
|
||||||
console.log('ON CLOSE');
|
console.log('ON CLOSE');
|
||||||
|
clearTimeout(timeoutId);
|
||||||
wstunneler = null;
|
wstunneler = null;
|
||||||
clientHandlers.closeAll();
|
clientHandlers.closeAll();
|
||||||
|
|
||||||
if (!authenticated) {
|
if (!authenticated) {
|
||||||
console.info('[close] failed on first attempt... check authentication.');
|
console.info('[close] failed on first attempt... check authentication.');
|
||||||
|
timeoutId = null;
|
||||||
}
|
}
|
||||||
else if (retry) {
|
else if (retry) {
|
||||||
console.info('[retry] disconnected and waiting...');
|
console.info('[retry] disconnected and waiting...');
|
||||||
retryTimeout = setTimeout(connect, 5000);
|
timeoutId = setTimeout(connect, 5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +237,7 @@ function run(copts) {
|
||||||
, sendMessage: function (msg) {
|
, sendMessage: function (msg) {
|
||||||
if (wstunneler) {
|
if (wstunneler) {
|
||||||
try {
|
try {
|
||||||
wstunneler.send(msg, {binary: true})
|
wstunneler.send(msg, {binary: true});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('[sendMessage] error sending websocket message', err);
|
console.warn('[sendMessage] error sending websocket message', err);
|
||||||
}
|
}
|
||||||
|
@ -204,7 +249,7 @@ function run(copts) {
|
||||||
if (!retry) {
|
if (!retry) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
retryTimeout = null;
|
timeoutId = null;
|
||||||
var machine = require('tunnel-packer').create(packerHandlers);
|
var machine = require('tunnel-packer').create(packerHandlers);
|
||||||
|
|
||||||
console.info("[connect] '" + copts.stunneld + "'");
|
console.info("[connect] '" + copts.stunneld + "'");
|
||||||
|
@ -212,7 +257,12 @@ function run(copts) {
|
||||||
wstunneler.on('open', wsHandlers.onOpen);
|
wstunneler.on('open', wsHandlers.onOpen);
|
||||||
wstunneler.on('close', wsHandlers.onClose);
|
wstunneler.on('close', wsHandlers.onClose);
|
||||||
wstunneler.on('error', wsHandlers.onError);
|
wstunneler.on('error', wsHandlers.onError);
|
||||||
|
|
||||||
|
// Our library will automatically handle sending the pong respose to ping requests.
|
||||||
|
wstunneler.on('ping', wsHandlers.refreshTimeout);
|
||||||
|
wstunneler.on('pong', wsHandlers.refreshTimeout);
|
||||||
wstunneler.on('message', function (data, flags) {
|
wstunneler.on('message', function (data, flags) {
|
||||||
|
wsHandlers.refreshTimeout();
|
||||||
if (data.error || '{' === data[0]) {
|
if (data.error || '{' === data[0]) {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
return;
|
return;
|
||||||
|
@ -231,9 +281,9 @@ function run(copts) {
|
||||||
process.removeListener('SIGINT', sigHandler);
|
process.removeListener('SIGINT', sigHandler);
|
||||||
|
|
||||||
retry = false;
|
retry = false;
|
||||||
if (retryTimeout) {
|
if (timeoutId) {
|
||||||
clearTimeout(retryTimeout);
|
clearTimeout(timeoutId);
|
||||||
retryTimeout = null;
|
timeoutId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wstunneler) {
|
if (wstunneler) {
|
||||||
|
|
Loading…
Reference in New Issue