mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-21 12:45:50 +00:00
[TASK] emit connected and disconnected events from api
This commit is contained in:
@@ -61,6 +61,8 @@
|
||||
- [API Events](#api-events)
|
||||
- [ledger](#ledger)
|
||||
- [error](#error)
|
||||
- [connected](#connected)
|
||||
- [disconnected](#disconnected)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
@@ -90,6 +92,14 @@ const api = new RippleAPI({
|
||||
api.on('error', (errorCode, errorMessage) => {
|
||||
console.log(errorCode + ': ' + errorMessage);
|
||||
});
|
||||
api.on('connected', () => {
|
||||
console.log('connected');
|
||||
});
|
||||
api.on('disconnected', (code) => {
|
||||
// code - [close code](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent) sent by the server
|
||||
// will be 1000 if this was normal closure
|
||||
console.log('disconnected, code:', code);
|
||||
});
|
||||
api.connect().then(() => {
|
||||
/* insert code here */
|
||||
}).then(() => {
|
||||
@@ -3593,3 +3603,35 @@ api.on('error', (errorCode, errorMessage, data) => {
|
||||
tooBusy: The server is too busy to help you now.
|
||||
```
|
||||
|
||||
## connected
|
||||
|
||||
This event is emitted after connection successfully opened.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
api.on('connected', () => {
|
||||
console.log('Connection is open now.');
|
||||
});
|
||||
```
|
||||
|
||||
## disconnected
|
||||
|
||||
This event is emitted when connection is closed.
|
||||
|
||||
### Return Value
|
||||
|
||||
The only parameter is a number containing the [close code](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent) send by the server.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
api.on('disconnected', (code) => {
|
||||
if (code !== 1000) {
|
||||
console.log('Connection is closed due to error.');
|
||||
} else {
|
||||
console.log('Connection is closed normally.');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
@@ -11,6 +11,14 @@ const api = new RippleAPI({
|
||||
api.on('error', (errorCode, errorMessage) => {
|
||||
console.log(errorCode + ': ' + errorMessage);
|
||||
});
|
||||
api.on('connected', () => {
|
||||
console.log('connected');
|
||||
});
|
||||
api.on('disconnected', (code) => {
|
||||
// code - [close code](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent) sent by the server
|
||||
// will be 1000 if this was normal closure
|
||||
console.log('disconnected, code:', code);
|
||||
});
|
||||
api.connect().then(() => {
|
||||
/* insert code here */
|
||||
}).then(() => {
|
||||
|
||||
@@ -47,3 +47,35 @@ api.on('error', (errorCode, errorMessage, data) => {
|
||||
```
|
||||
tooBusy: The server is too busy to help you now.
|
||||
```
|
||||
|
||||
## connected
|
||||
|
||||
This event is emitted after connection successfully opened.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
api.on('connected', () => {
|
||||
console.log('Connection is open now.');
|
||||
});
|
||||
```
|
||||
|
||||
## disconnected
|
||||
|
||||
This event is emitted when connection is closed.
|
||||
|
||||
### Return Value
|
||||
|
||||
The only parameter is a number containing the [close code](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent) send by the server.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
api.on('disconnected', (code) => {
|
||||
if (code !== 1000) {
|
||||
console.log('Connection is closed due to error.');
|
||||
} else {
|
||||
console.log('Connection is closed normally.');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
'use strict'; // eslint-disable-line
|
||||
|
||||
/* eslint-disable max-len */
|
||||
// Enable core-js polyfills. This allows use of ES6/7 extensions listed here:
|
||||
@@ -89,6 +89,12 @@ class RippleAPI extends EventEmitter {
|
||||
this.connection.on('error', (errorCode, errorMessage, data) => {
|
||||
this.emit('error', errorCode, errorMessage, data);
|
||||
});
|
||||
this.connection.on('connected', () => {
|
||||
this.emit('connected');
|
||||
});
|
||||
this.connection.on('disconnected', onError => {
|
||||
this.emit('disconnected', onError);
|
||||
});
|
||||
} else {
|
||||
// use null object pattern to provide better error message if user
|
||||
// tries to call a method that requires a connection
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'; // eslint-disable-line
|
||||
|
||||
const _ = require('lodash');
|
||||
const {EventEmitter} = require('events');
|
||||
const WebSocket = require('ws');
|
||||
@@ -97,36 +99,42 @@ class Connection extends EventEmitter {
|
||||
return this._state === WebSocket.OPEN && this._isReady;
|
||||
}
|
||||
|
||||
_onUnexpectedClose(resolve, reject) {
|
||||
_onUnexpectedClose(beforeOpen, resolve, reject, code) {
|
||||
if (this._onOpenErrorBound) {
|
||||
this._ws.removeListener('error', this._onOpenErrorBound);
|
||||
this._onOpenErrorBound = null;
|
||||
}
|
||||
this._ws = null;
|
||||
this._isReady = false;
|
||||
if (_.isFunction(resolve)) {
|
||||
if (beforeOpen) {
|
||||
// connection was closed before it was properly opened, so we must return
|
||||
// error to connect's caller
|
||||
this.connect().then(resolve, reject);
|
||||
} else {
|
||||
this.emit('disconnected', true);
|
||||
// if first parameter ws lib sends close code,
|
||||
// but sometimes it forgots about it, so default to 1006 - CLOSE_ABNORMAL
|
||||
this.emit('disconnected', code || 1006);
|
||||
this._retryConnect();
|
||||
}
|
||||
}
|
||||
|
||||
_retryConnect() {
|
||||
this._retry += 1;
|
||||
const retryTimeout = (this._retry < 40)
|
||||
_calculateTimeout(retriesCount) {
|
||||
return (retriesCount < 40)
|
||||
// First, for 2 seconds: 20 times per second
|
||||
? (1000 / 20)
|
||||
: (this._retry < 40 + 60)
|
||||
: (retriesCount < 40 + 60)
|
||||
// Then, for 1 minute: once per second
|
||||
? (1000)
|
||||
: (this._retry < 40 + 60 + 60)
|
||||
: (retriesCount < 40 + 60 + 60)
|
||||
// Then, for 10 minutes: once every 10 seconds
|
||||
? (10 * 1000)
|
||||
// Then: once every 30 seconds
|
||||
: (30 * 1000);
|
||||
}
|
||||
|
||||
_retryConnect() {
|
||||
this._retry += 1;
|
||||
const retryTimeout = this._calculateTimeout(this._retry);
|
||||
this._retryTimer = setTimeout(() => {
|
||||
this.connect().catch(this._retryConnect.bind(this));
|
||||
}, retryTimeout);
|
||||
@@ -139,7 +147,8 @@ class Connection extends EventEmitter {
|
||||
|
||||
_onOpen() {
|
||||
this._ws.removeListener('close', this._onUnexpectedCloseBound);
|
||||
this._onUnexpectedCloseBound = this._onUnexpectedClose.bind(this);
|
||||
this._onUnexpectedCloseBound =
|
||||
this._onUnexpectedClose.bind(this, false, null, null);
|
||||
this._ws.once('close', this._onUnexpectedCloseBound);
|
||||
|
||||
this._ws.removeListener('error', this._onOpenErrorBound);
|
||||
@@ -234,7 +243,7 @@ class Connection extends EventEmitter {
|
||||
// resolve connect's promise after reconnect in that case.
|
||||
// after open event we will rebound _onUnexpectedCloseBound
|
||||
// without resolve and reject functions
|
||||
this._onUnexpectedCloseBound = this._onUnexpectedClose.bind(this,
|
||||
this._onUnexpectedCloseBound = this._onUnexpectedClose.bind(this, true,
|
||||
resolve, reject);
|
||||
this._ws.once('close', this._onUnexpectedCloseBound);
|
||||
this._ws.once('open', () => this._onOpen().then(resolve, reject));
|
||||
@@ -252,10 +261,10 @@ class Connection extends EventEmitter {
|
||||
this._ws.once('close', resolve);
|
||||
} else {
|
||||
this._ws.removeListener('close', this._onUnexpectedCloseBound);
|
||||
this._ws.once('close', () => {
|
||||
this._ws.once('close', code => {
|
||||
this._ws = null;
|
||||
this._isReady = false;
|
||||
this.emit('disconnected', false);
|
||||
this.emit('disconnected', code || 1000); // 1000 - CLOSE_NORMAL
|
||||
resolve();
|
||||
});
|
||||
this._ws.close();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
'use strict'; // eslint-disable-line
|
||||
/* eslint-disable max-nested-callbacks */
|
||||
|
||||
const _ = require('lodash');
|
||||
@@ -212,7 +213,9 @@ describe('Connection', function() {
|
||||
|
||||
let connectsCount = 0;
|
||||
let disconnectsCount = 0;
|
||||
this.api.connection.on('disconnected', () => {
|
||||
let code = 0;
|
||||
this.api.connection.on('disconnected', _code => {
|
||||
code = _code;
|
||||
disconnectsCount += 1;
|
||||
});
|
||||
this.api.connection.on('connected', () => {
|
||||
@@ -224,6 +227,9 @@ describe('Connection', function() {
|
||||
if (disconnectsCount !== 3) {
|
||||
done(new Error('disconnectsCount must be equal to 3 (got ' +
|
||||
disconnectsCount + ' instead)'));
|
||||
} else if (code !== 1006) {
|
||||
done(new Error('disconnect must send code 1006 (got ' + code +
|
||||
' instead)'));
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
@@ -233,6 +239,36 @@ describe('Connection', function() {
|
||||
breakConnection();
|
||||
});
|
||||
|
||||
it('should emit disconnected event with code 1000 (CLOSE_NORMAL)',
|
||||
function(done
|
||||
) {
|
||||
this.api.once('disconnected', code => {
|
||||
assert.strictEqual(code, 1000);
|
||||
done();
|
||||
});
|
||||
this.api.disconnect();
|
||||
});
|
||||
|
||||
it('should emit disconnected event with code 1006 (CLOSE_ABNORMAL)',
|
||||
function(done
|
||||
) {
|
||||
if (process.browser) {
|
||||
// can't be tested in browser this way, so skipping
|
||||
done();
|
||||
return;
|
||||
}
|
||||
this.api.once('disconnected', code => {
|
||||
assert.strictEqual(code, 1006);
|
||||
done();
|
||||
});
|
||||
this.mockRippled.close();
|
||||
});
|
||||
|
||||
it('should emit connected event on after reconnect', function(done) {
|
||||
this.api.once('connected', done);
|
||||
this.api.connection._ws.close();
|
||||
});
|
||||
|
||||
it('Multiply connect calls', function() {
|
||||
return this.api.connect().then(() => {
|
||||
return this.api.connect();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict'; // eslint-disable-line
|
||||
|
||||
const net = require('net');
|
||||
const RippleAPI = require('ripple-api').RippleAPI;
|
||||
const RippleAPIBroadcast = require('ripple-api').RippleAPIBroadcast;
|
||||
|
||||
Reference in New Issue
Block a user