Skip to content

Commit

Permalink
Auto re-connect when connection is closed - Fixing web3#1354
Browse files Browse the repository at this point in the history
  • Loading branch information
linmao-song committed Apr 13, 2018
1 parent e69054d commit b8ae407
Showing 1 changed file with 66 additions and 48 deletions.
114 changes: 66 additions & 48 deletions packages/web3-providers-ws/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,54 +50,7 @@ var WebsocketProvider = function WebsocketProvider(url, headers) {
var _this = this;
this.responseCallbacks = {};
this.notificationCallbacks = [];

// The w3cwebsocket implementation does not support Basic Auth
// username/password in the URL. So generate the basic auth header, and
// pass through with any additional headers supplied in constructor
var parsedURL = parseURL(url);
headers = headers || {};
if (parsedURL.username && parsedURL.password) {
headers.authorization = 'Basic ' + _btoa(parsedURL.username + ':' + parsedURL.password);
}

this.connection = new Ws(url, undefined, undefined, headers);

this.addDefaultEvents();


// LISTEN FOR CONNECTION RESPONSES
this.connection.onmessage = function(e) {
/*jshint maxcomplexity: 6 */
var data = (typeof e.data === 'string') ? e.data : '';

_this._parseResponse(data).forEach(function(result){

var id = null;

// get the id which matches the returned id
if(_.isArray(result)) {
result.forEach(function(load){
if(_this.responseCallbacks[load.id])
id = load.id;
});
} else {
id = result.id;
}

// notification
if(!id && result.method.indexOf('_subscription') !== -1) {
_this.notificationCallbacks.forEach(function(callback){
if(_.isFunction(callback))
callback(result);
});

// fire the callback
} else if(_this.responseCallbacks[id]) {
_this.responseCallbacks[id](null, result);
delete _this.responseCallbacks[id];
}
});
};
this.connect(url, headers);
};

/**
Expand All @@ -117,6 +70,11 @@ WebsocketProvider.prototype.addDefaultEvents = function(){

// reset all requests and callbacks
_this.reset();

// Automatically attempt re-connect every second
setTimeout(function() {
_this.connect(_this.url, _this.headers);
}, 1000);
};

// this.connection.on('timeout', function(){
Expand Down Expand Up @@ -347,4 +305,64 @@ WebsocketProvider.prototype.reset = function () {
this.addDefaultEvents();
};

/**
connect to the given URL
@method connect
@param {String} url
@param {Object} headers
*/
WebsocketProvider.prototype.connect = function(url, headers){
var _this = this;
this.url = url;
this.headers = headers;

// The w3cwebsocket implementation does not support Basic Auth
// username/password in the URL. So generate the basic auth header, and
// pass through with any additional headers supplied in constructor
var parsedURL = parseURL(url);
headers = headers || {};
if (parsedURL.username && parsedURL.password) {
headers.authorization = 'Basic ' + _btoa(parsedURL.username + ':' + parsedURL.password);
}

this.connection = new Ws(url, undefined, undefined, headers);

this.addDefaultEvents();

// LISTEN FOR CONNECTION RESPONSES
this.connection.onmessage = function(e) {
/*jshint maxcomplexity: 6 */
var data = (typeof e.data === 'string') ? e.data : '';

_this._parseResponse(data).forEach(function(result){

var id = null;

// get the id which matches the returned id
if(_.isArray(result)) {
result.forEach(function(load){
if(_this.responseCallbacks[load.id])
id = load.id;
});
} else {
id = result.id;
}

// notification
if(!id && result.method.indexOf('_subscription') !== -1) {
_this.notificationCallbacks.forEach(function(callback){
if(_.isFunction(callback))
callback(result);
});

// fire the callback
} else if(_this.responseCallbacks[id]) {
_this.responseCallbacks[id](null, result);
delete _this.responseCallbacks[id];
}
});
};
}

module.exports = WebsocketProvider;

0 comments on commit b8ae407

Please sign in to comment.