123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- /**
- * Dependencies
- */
- var delegate = require('delegates');
- var net = require('net');
- /**
- * Socket v2
- */
- function Socket (options) {
- this.socket = new net.Socket(options);
-
- this.monitor();
- }
- /**
- * Socket prototype
- */
- var socket = Socket.prototype;
- /**
- * Remember connection arguments for reconnection
- */
- socket.connect = function () {
- this._connectArgs = arguments;
-
- return this.socket.connect.apply(this.socket, arguments);
- };
- /**
- * Stop monitoring
- */
- socket.destroy = function () {
- clearTimeout(this._connectTimeout);
- this.socket.removeAllListeners();
-
- return this.socket.destroy();
- };
- /**
- * Reconnect on close
- */
- socket.monitor = function () {
- var self = this;
-
- var backoff = 1.5;
- var delay = 1000;
-
- this.socket.on('connect', function () {
- clearTimeout(this._connectTimeout);
- delay = 1000;
- });
-
- this.socket.on('close', function () {
- this._connectTimeout = setTimeout(function () {
- self._reconnect();
- }, delay);
- });
-
- this.socket.on('error', function (err) {
- if (err.code === 'ECONNREFUSED' || err.code === 'ECONNRESET') {
- return this._connectTimout = setTimeout(function () {
- self._reconnect();
- }, delay);
-
- delay *= backoff;
- };
-
- throw err;
- });
- };
- socket._reconnect = function () {
- if (this.socket._connecting) return;
-
- this.socket.connect.apply(this.socket, this._connectArgs);
- };
- /**
- * Proxy net.Socket methods and properties
- */
- var methods = [
- // net.Socket
- 'setEncoding',
- 'write',
- 'end',
- 'pause',
- 'resume',
- 'setTimeout',
- 'setNoDelay',
- 'setKeepAlive',
- 'address',
- 'unref',
- 'ref',
-
- // EventEmitter
- 'addListener',
- 'on',
- 'once',
- 'removeListener',
- 'removeAllListeners',
- 'setMaxListeners',
- 'listeners',
- 'emit'
- ];
- var properties = [
- // net.Socket
- 'bufferSize',
- 'remoteAddress',
- 'remoteFamily',
- 'remotePort',
- 'localAddress',
- 'localPort',
- 'bytesRead',
- 'bytesWritten',
-
- // EventEmitter
- 'defaultMaxListeners',
- ];
- methods.forEach(function (method) {
- socket[method] = function () {
- return this.socket[method].apply(this.socket, arguments);
- };
- });
- properties.forEach(function (property) {
- delegate(socket, 'socket').access(property);
- });
- /**
- * Expose connect method
- */
- exports.connect = exports.createConnection = function (port, host, connectionListener) {
- var options = {};
-
- if (typeof port === 'object') options = port;
- if (typeof port === 'string') options.path = port;
- if (typeof port === 'number') options.port = port;
-
- if (typeof host === 'function') connectionListener = host;
- if (typeof host === 'string') options.host = host;
-
- var socket = new Socket();
- socket.connect(options, connectionListener);
- return socket;
- };
|