implemented timeout over websocket connection
This commit is contained in:
		
							parent
							
								
									304c3200a0
								
							
						
					
					
						commit
						06867530d8
					
				@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user