mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 20:25:48 +00:00
Merge pull request #128 from ripple/passive-hostid
Passively acquire hostid (actually pubkey_node) if present in response t...
This commit is contained in:
@@ -51,26 +51,26 @@ function Server(remote, opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._remote = remote;
|
this._remote = remote;
|
||||||
this._opts = opts;
|
this._opts = opts;
|
||||||
this._ws = void(0);
|
this._ws = void(0);
|
||||||
|
|
||||||
this._connected = false;
|
this._connected = false;
|
||||||
this._shouldConnect = false;
|
this._shouldConnect = false;
|
||||||
this._state = 'offline';
|
this._state = 'offline';
|
||||||
|
|
||||||
this._id = 0;
|
this._id = 0; // request ID
|
||||||
this._retry = 0;
|
this._retry = 0;
|
||||||
this._requests = { };
|
this._requests = { };
|
||||||
|
|
||||||
this._load_base = 256;
|
this._load_base = 256;
|
||||||
this._load_factor = 256;
|
this._load_factor = 256;
|
||||||
|
|
||||||
this._fee = 10;
|
this._fee = 10;
|
||||||
this._fee_ref = 10;
|
this._fee_ref = 10;
|
||||||
this._fee_base = 10;
|
this._fee_base = 10;
|
||||||
this._reserve_base = void(0);
|
this._reserve_base = void(0);
|
||||||
this._reserve_inc = void(0);
|
this._reserve_inc = void(0);
|
||||||
this._fee_cushion = this._remote.fee_cushion;
|
this._fee_cushion = this._remote.fee_cushion;
|
||||||
|
|
||||||
this._lastLedgerIndex = NaN;
|
this._lastLedgerIndex = NaN;
|
||||||
this._lastLedgerClose = NaN;
|
this._lastLedgerClose = NaN;
|
||||||
@@ -82,22 +82,18 @@ function Server(remote, opts) {
|
|||||||
response: 1
|
response: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._pubkey_node = '';
|
||||||
|
|
||||||
this._url = this._opts.url = (this._opts.secure ? 'wss://' : 'ws://')
|
this._url = this._opts.url = (this._opts.secure ? 'wss://' : 'ws://')
|
||||||
+ this._opts.host + ':' + this._opts.port;
|
+ this._opts.host + ':' + this._opts.port;
|
||||||
|
|
||||||
this._hostid = '';
|
this.on('message', function onMessage(message) {
|
||||||
|
|
||||||
function onMessage(message) {
|
|
||||||
self._handleMessage(message);
|
self._handleMessage(message);
|
||||||
};
|
});
|
||||||
|
|
||||||
this.on('message', onMessage);
|
this.on('response_subscribe', function onSubscribe(message) {
|
||||||
|
|
||||||
function onSubscribeResponse(message) {
|
|
||||||
self._handleResponseSubscribe(message);
|
self._handleResponseSubscribe(message);
|
||||||
};
|
});
|
||||||
|
|
||||||
this.on('response_subscribe', onSubscribeResponse);
|
|
||||||
|
|
||||||
function setActivityInterval() {
|
function setActivityInterval() {
|
||||||
var interval = self._checkActivity.bind(self);
|
var interval = self._checkActivity.bind(self);
|
||||||
@@ -111,26 +107,34 @@ function Server(remote, opts) {
|
|||||||
|
|
||||||
this.once('ledger_closed', setActivityInterval);
|
this.once('ledger_closed', setActivityInterval);
|
||||||
|
|
||||||
this._remote.on('ledger_closed', function(ledger) {
|
this._remote.on('ledger_closed', function onRemoteLedgerClose(ledger) {
|
||||||
self._updateScore('ledgerclose', ledger);
|
self._updateScore('ledgerclose', ledger);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('response_ping', function(message, request) {
|
this.on('response_ping', function onPingResponse(message, request) {
|
||||||
self._updateScore('response', request);
|
self._updateScore('response', request);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('load_changed', function(load) {
|
this.on('load_changed', function onLoadChange(load) {
|
||||||
self._updateScore('loadchange', load);
|
self._updateScore('loadchange', load);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('response_server_info', function(message) {
|
// If server is not up-to-date, request server_info
|
||||||
try {
|
// for getting pubkey_node & hostid information.
|
||||||
self._hostid = '(' + message.info.pubkey_node + ')';
|
// Otherwise this information is available on the
|
||||||
} catch (e) {
|
// initial server subscribe response
|
||||||
|
this.on('connect', function requestServerID() {
|
||||||
|
if (self._pubkey_node) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
this.on('connect', function() {
|
self.on('response_server_info', function setServerID(message) {
|
||||||
|
try {
|
||||||
|
self._pubkey_node = message.info.pubkey_node;
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
self._request(self._remote.requestServerInfo());
|
self._request(self._remote.requestServerInfo());
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -181,7 +185,7 @@ Server.websocketConstructor = function() {
|
|||||||
Server.prototype._setState = function(state) {
|
Server.prototype._setState = function(state) {
|
||||||
if (state !== this._state) {
|
if (state !== this._state) {
|
||||||
if (this._remote.trace) {
|
if (this._remote.trace) {
|
||||||
log.info('set_state:', this._opts.url, this._hostid, state);
|
log.info(this.getHostID(), 'set_state:', state);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._state = state;
|
this._state = state;
|
||||||
@@ -213,7 +217,7 @@ Server.prototype._setState = function(state) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Server.prototype._checkActivity = function() {
|
Server.prototype._checkActivity = function() {
|
||||||
if (!this._connected) {
|
if (!this.isConnected()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +228,9 @@ Server.prototype._checkActivity = function() {
|
|||||||
var delta = (Date.now() - this._lastLedgerClose);
|
var delta = (Date.now() - this._lastLedgerClose);
|
||||||
|
|
||||||
if (delta > (1000 * 25)) {
|
if (delta > (1000 * 25)) {
|
||||||
log.info('reconnect: activity delta:', delta);
|
if (this._remote.trace) {
|
||||||
|
log.info(this.getHostID(), 'reconnect: activity delta:', delta);
|
||||||
|
}
|
||||||
this.reconnect();
|
this.reconnect();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -242,7 +248,7 @@ Server.prototype._checkActivity = function() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Server.prototype._updateScore = function(type, data) {
|
Server.prototype._updateScore = function(type, data) {
|
||||||
if (!this._connected) {
|
if (!this.isConnected()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +274,9 @@ Server.prototype._updateScore = function(type, data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this._score > 1e3) {
|
if (this._score > 1e3) {
|
||||||
log.info('reconnect: score:', this._score);
|
if (this._remote.trace) {
|
||||||
|
log.info(this.getHostID(), 'reconnect: score:', this._score);
|
||||||
|
}
|
||||||
this.reconnect();
|
this.reconnect();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -293,8 +301,9 @@ Server.prototype._remoteAddress = function() {
|
|||||||
* Get the server's hostid
|
* Get the server's hostid
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Server.prototype.getHostID = function() {
|
Server.prototype.getHostID =
|
||||||
return this._hostid;
|
Server.prototype.getServerID = function() {
|
||||||
|
return this._url + ' (' + (this._pubkey_node ? this._pubkey_node : '') + ')';
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -306,7 +315,7 @@ Server.prototype.getHostID = function() {
|
|||||||
Server.prototype.disconnect = function() {
|
Server.prototype.disconnect = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (!this._connected) {
|
if (!this.isConnected()) {
|
||||||
this.once('socket_open', function() {
|
this.once('socket_open', function() {
|
||||||
self.disconnect();
|
self.disconnect();
|
||||||
});
|
});
|
||||||
@@ -372,7 +381,7 @@ Server.prototype.connect = function() {
|
|||||||
// recently received a message from the server and the WebSocket has not
|
// recently received a message from the server and the WebSocket has not
|
||||||
// reported any issues either. If we do fail to ping or the connection drops,
|
// reported any issues either. If we do fail to ping or the connection drops,
|
||||||
// we will automatically reconnect.
|
// we will automatically reconnect.
|
||||||
if (this._connected) {
|
if (this.isConnected()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +391,7 @@ Server.prototype.connect = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this._remote.trace) {
|
if (this._remote.trace) {
|
||||||
log.info('connect:', this._opts.url, this._hostid);
|
log.info(this.getServerID(), 'connect');
|
||||||
}
|
}
|
||||||
|
|
||||||
var ws = this._ws = new WebSocket(this._opts.url);
|
var ws = this._ws = new WebSocket(this._opts.url);
|
||||||
@@ -408,7 +417,7 @@ Server.prototype.connect = function() {
|
|||||||
self.emit('socket_error');
|
self.emit('socket_error');
|
||||||
|
|
||||||
if (self._remote.trace) {
|
if (self._remote.trace) {
|
||||||
log.info('onerror:', self._opts.url, self._hostid, e.data || e);
|
log.info(self.getServerID(), 'onerror:', e.data || e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Most connection errors for WebSockets are conveyed as 'close' events with
|
// Most connection errors for WebSockets are conveyed as 'close' events with
|
||||||
@@ -432,7 +441,7 @@ Server.prototype.connect = function() {
|
|||||||
ws.onclose = function onClose() {
|
ws.onclose = function onClose() {
|
||||||
if (ws === self._ws) {
|
if (ws === self._ws) {
|
||||||
if (self._remote.trace) {
|
if (self._remote.trace) {
|
||||||
log.info('onclose:', self._opts.url, self._hostid, ws.readyState);
|
log.info(self.getServerID(), 'onclose:', ws.readyState);
|
||||||
}
|
}
|
||||||
self._handleClose();
|
self._handleClose();
|
||||||
}
|
}
|
||||||
@@ -465,7 +474,7 @@ Server.prototype._retryConnect = function() {
|
|||||||
function connectionRetry() {
|
function connectionRetry() {
|
||||||
if (self._shouldConnect) {
|
if (self._shouldConnect) {
|
||||||
if (self._remote.trace) {
|
if (self._remote.trace) {
|
||||||
log.info('retry', self._opts.url, self._hostid);
|
log.info(self.getServerID(), 'retry', self._retry);
|
||||||
}
|
}
|
||||||
self.connect();
|
self.connect();
|
||||||
}
|
}
|
||||||
@@ -543,6 +552,7 @@ Server.prototype._handleServerStatus = function(message) {
|
|||||||
// This message is only received when online.
|
// This message is only received when online.
|
||||||
// As we are connected, it is the definitive final state.
|
// As we are connected, it is the definitive final state.
|
||||||
var isOnline = ~Server.onlineStates.indexOf(message.server_status);
|
var isOnline = ~Server.onlineStates.indexOf(message.server_status);
|
||||||
|
|
||||||
this._setState(isOnline ? 'online' : 'offline');
|
this._setState(isOnline ? 'online' : 'offline');
|
||||||
|
|
||||||
if (!Server.isLoadStatus(message)) {
|
if (!Server.isLoadStatus(message)) {
|
||||||
@@ -571,14 +581,14 @@ Server.prototype._handleResponse = function(message) {
|
|||||||
|
|
||||||
if (!request) {
|
if (!request) {
|
||||||
if (this._remote.trace) {
|
if (this._remote.trace) {
|
||||||
log.info('UNEXPECTED:', this._opts.url, this._hostid, message);
|
log.info(this.getServerID(), 'UNEXPECTED:', message);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.status === 'success') {
|
if (message.status === 'success') {
|
||||||
if (this._remote.trace) {
|
if (this._remote.trace) {
|
||||||
log.info('response:', this._opts.url, this._hostid, message);
|
log.info(this.getServerID(), 'response:', message);
|
||||||
}
|
}
|
||||||
|
|
||||||
var command = request.message.command;
|
var command = request.message.command;
|
||||||
@@ -592,22 +602,20 @@ Server.prototype._handleResponse = function(message) {
|
|||||||
});
|
});
|
||||||
} else if (message.error) {
|
} else if (message.error) {
|
||||||
if (this._remote.trace) {
|
if (this._remote.trace) {
|
||||||
log.info('error:', this._opts.url, this._hostid, message);
|
log.info(this.getServerID(), 'error:', message);
|
||||||
}
|
}
|
||||||
|
|
||||||
var error = {
|
request.emit('error', {
|
||||||
error: 'remoteError',
|
error: 'remoteError',
|
||||||
error_message: 'Remote reported an error.',
|
error_message: 'Remote reported an error.',
|
||||||
remote: message
|
remote: message
|
||||||
};
|
});
|
||||||
|
|
||||||
request.emit('error', error);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Server.prototype._handlePathFind = function(message) {
|
Server.prototype._handlePathFind = function(message) {
|
||||||
if (this._remote.trace) {
|
if (this._remote.trace) {
|
||||||
log.info('path_find:', this._opts.url, this._hostid, message);
|
log.info(this.getServerID(), 'path_find:', message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -619,9 +627,6 @@ Server.prototype._handlePathFind = function(message) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Server.prototype._handleResponseSubscribe = function(message) {
|
Server.prototype._handleResponseSubscribe = function(message) {
|
||||||
if (~(Server.onlineStates.indexOf(message.server_status))) {
|
|
||||||
this._setState('online');
|
|
||||||
}
|
|
||||||
if (Server.isLoadStatus(message)) {
|
if (Server.isLoadStatus(message)) {
|
||||||
this._load_base = message.load_base || 256;
|
this._load_base = message.load_base || 256;
|
||||||
this._load_factor = message.load_factor || 256;
|
this._load_factor = message.load_factor || 256;
|
||||||
@@ -630,6 +635,12 @@ Server.prototype._handleResponseSubscribe = function(message) {
|
|||||||
this._reserve_base = message.reserve_base;
|
this._reserve_base = message.reserve_base;
|
||||||
this._reserve_inc = message.reserve_inc;
|
this._reserve_inc = message.reserve_inc;
|
||||||
}
|
}
|
||||||
|
if (message.pubkey_node) {
|
||||||
|
this._pubkey_node = message.pubkey_node;
|
||||||
|
}
|
||||||
|
if (~(Server.onlineStates.indexOf(message.server_status))) {
|
||||||
|
this._setState('online');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -665,7 +676,7 @@ Server.isLoadStatus = function(message) {
|
|||||||
Server.prototype._sendMessage = function(message) {
|
Server.prototype._sendMessage = function(message) {
|
||||||
if (this._ws) {
|
if (this._ws) {
|
||||||
if (this._remote.trace) {
|
if (this._remote.trace) {
|
||||||
log.info('request:', this._opts.url, this._hostid, message);
|
log.info(this.getServerID(), 'request:', message);
|
||||||
}
|
}
|
||||||
this._ws.send(JSON.stringify(message));
|
this._ws.send(JSON.stringify(message));
|
||||||
}
|
}
|
||||||
@@ -687,7 +698,7 @@ Server.prototype._request = function(request) {
|
|||||||
// Only bother if we are still connected.
|
// Only bother if we are still connected.
|
||||||
if (!this._ws) {
|
if (!this._ws) {
|
||||||
if (this._remote.trace) {
|
if (this._remote.trace) {
|
||||||
log.info('request: DROPPING:', self._opts.url, self._hostid, request.message);
|
log.info(this.getServerID(), 'request: DROPPING:', request.message);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1025,15 +1025,13 @@ describe('Server', function() {
|
|||||||
server.once('connect', function() {
|
server.once('connect', function() {
|
||||||
var receivedSubscribe = false;
|
var receivedSubscribe = false;
|
||||||
|
|
||||||
assert.strictEqual(server._hostid, '');
|
|
||||||
|
|
||||||
server.once('response_server_info', function() {
|
server.once('response_server_info', function() {
|
||||||
receivedSubscribe = true;
|
receivedSubscribe = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
server.once('disconnect', function() {
|
server.once('disconnect', function() {
|
||||||
assert(receivedSubscribe);
|
assert(receivedSubscribe);
|
||||||
assert.strictEqual(server.getHostID(), '(n94pSqypSfddzAVj9qoezHyUoetsrMnwgNuBqRJ3WHvM8aMMf7rW)');
|
assert.strictEqual(server.getServerID(), 'ws://localhost:5748 (n94pSqypSfddzAVj9qoezHyUoetsrMnwgNuBqRJ3WHvM8aMMf7rW)');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user