diff options
author | Fabio Berger <me@fabioberger.com> | 2018-02-26 10:32:12 +0800 |
---|---|---|
committer | Fabio Berger <me@fabioberger.com> | 2018-02-26 10:32:12 +0800 |
commit | fffaafe4c996ac0c458dd6cb9e3598b1d93b7aa4 (patch) | |
tree | 21f9398ba2975bda4706fb8f54c0c717b88ecfd4 /packages/connect/src | |
parent | 66b36f6d8f7c0f0487e53badb035ac50e1ec5669 (diff) | |
parent | 709fa9e02ec21cee9fc145b4a578742c8dd190aa (diff) | |
download | dexon-sol-tools-fffaafe4c996ac0c458dd6cb9e3598b1d93b7aa4.tar dexon-sol-tools-fffaafe4c996ac0c458dd6cb9e3598b1d93b7aa4.tar.gz dexon-sol-tools-fffaafe4c996ac0c458dd6cb9e3598b1d93b7aa4.tar.bz2 dexon-sol-tools-fffaafe4c996ac0c458dd6cb9e3598b1d93b7aa4.tar.lz dexon-sol-tools-fffaafe4c996ac0c458dd6cb9e3598b1d93b7aa4.tar.xz dexon-sol-tools-fffaafe4c996ac0c458dd6cb9e3598b1d93b7aa4.tar.zst dexon-sol-tools-fffaafe4c996ac0c458dd6cb9e3598b1d93b7aa4.zip |
Merge branch 'development' into moveOutDocGenerator
* development: (36 commits)
Fix english translations
Fix footer on mobile
re-add google analytics code
Fix Russian translation
Move all dependencies on @0xproject/types out of devDependencies
Slight improvement to footer
Fix a few Korean translations
Address feedback
Use source tree hash instead of compile flag
Fix race condition
Update CHANGELOG
Delete artifacts directory
Add generated contract artifacts to gitignore
Check dependencies when determining if should be recompiled
Update CHANGELOG
Remove unused CHANGELOG entry
Remove unused import
Change assert.doesConformToShema interface
Remove a type assertion
Publish
...
Diffstat (limited to 'packages/connect/src')
-rw-r--r-- | packages/connect/src/http_client.ts | 9 | ||||
-rw-r--r-- | packages/connect/src/index.ts | 1 | ||||
-rw-r--r-- | packages/connect/src/schemas/schemas.ts | 2 | ||||
-rw-r--r-- | packages/connect/src/schemas/websocket_orderbook_channel_config_schema.ts | 10 | ||||
-rw-r--r-- | packages/connect/src/types.ts | 7 | ||||
-rw-r--r-- | packages/connect/src/ws_orderbook_channel.ts | 36 |
6 files changed, 58 insertions, 7 deletions
diff --git a/packages/connect/src/http_client.ts b/packages/connect/src/http_client.ts index 9e5f0f448..cf0aaef0d 100644 --- a/packages/connect/src/http_client.ts +++ b/packages/connect/src/http_client.ts @@ -172,13 +172,12 @@ export class HttpClient implements Client { body: JSON.stringify(payload), headers, }); - const json = await response.json(); + const text = await response.text(); if (!response.ok) { - const errorString = `${response.status} - ${response.statusText}\n${requestType} ${url}\n${JSON.stringify( - json, - )}`; + const errorString = `${response.status} - ${response.statusText}\n${requestType} ${url}\n${text}`; throw Error(errorString); } - return json; + const result = !_.isEmpty(text) ? JSON.parse(text) : undefined; + return result; } } diff --git a/packages/connect/src/index.ts b/packages/connect/src/index.ts index 344a32e28..bb42384f9 100644 --- a/packages/connect/src/index.ts +++ b/packages/connect/src/index.ts @@ -17,4 +17,5 @@ export { TokenPairsItem, TokenPairsRequestOpts, TokenTradeInfo, + WebSocketOrderbookChannelConfig, } from './types'; diff --git a/packages/connect/src/schemas/schemas.ts b/packages/connect/src/schemas/schemas.ts index 0b8b798a9..b9a8472fb 100644 --- a/packages/connect/src/schemas/schemas.ts +++ b/packages/connect/src/schemas/schemas.ts @@ -3,6 +3,7 @@ import { orderBookRequestSchema } from './orderbook_request_schema'; import { ordersRequestOptsSchema } from './orders_request_opts_schema'; import { pagedRequestOptsSchema } from './paged_request_opts_schema'; import { tokenPairsRequestOptsSchema } from './token_pairs_request_opts_schema'; +import { webSocketOrderbookChannelConfigSchema } from './websocket_orderbook_channel_config_schema'; export const schemas = { feesRequestSchema, @@ -10,4 +11,5 @@ export const schemas = { ordersRequestOptsSchema, pagedRequestOptsSchema, tokenPairsRequestOptsSchema, + webSocketOrderbookChannelConfigSchema, }; diff --git a/packages/connect/src/schemas/websocket_orderbook_channel_config_schema.ts b/packages/connect/src/schemas/websocket_orderbook_channel_config_schema.ts new file mode 100644 index 000000000..81c0cac9c --- /dev/null +++ b/packages/connect/src/schemas/websocket_orderbook_channel_config_schema.ts @@ -0,0 +1,10 @@ +export const webSocketOrderbookChannelConfigSchema = { + id: '/WebSocketOrderbookChannelConfig', + type: 'object', + properties: { + heartbeatIntervalMs: { + type: 'number', + minimum: 10, + }, + }, +}; diff --git a/packages/connect/src/types.ts b/packages/connect/src/types.ts index 970eff498..5f837b0b3 100644 --- a/packages/connect/src/types.ts +++ b/packages/connect/src/types.ts @@ -44,6 +44,13 @@ export interface OrderbookChannel { } /* + * heartbeatInterval: Interval in milliseconds that the orderbook channel should ping the underlying websocket. Default: 15000 + */ +export interface WebSocketOrderbookChannelConfig { + heartbeatIntervalMs?: number; +} + +/* * baseTokenAddress: The address of token designated as the baseToken in the currency pair calculation of price * quoteTokenAddress: The address of token designated as the quoteToken in the currency pair calculation of price * snapshot: If true, a snapshot of the orderbook will be sent before the updates to the orderbook diff --git a/packages/connect/src/ws_orderbook_channel.ts b/packages/connect/src/ws_orderbook_channel.ts index 822a022f4..5aa730d8f 100644 --- a/packages/connect/src/ws_orderbook_channel.ts +++ b/packages/connect/src/ws_orderbook_channel.ts @@ -3,6 +3,7 @@ import { schemas } from '@0xproject/json-schemas'; import * as _ from 'lodash'; import * as WebSocket from 'websocket'; +import { schemas as clientSchemas } from './schemas/schemas'; import { OrderbookChannel, OrderbookChannelHandler, @@ -10,9 +11,13 @@ import { OrderbookChannelSubscriptionOpts, WebsocketClientEventType, WebsocketConnectionEventType, + WebSocketOrderbookChannelConfig, } from './types'; import { orderbookChannelMessageParser } from './utils/orderbook_channel_message_parser'; +const DEFAULT_HEARTBEAT_INTERVAL_MS = 15000; +const MINIMUM_HEARTBEAT_INTERVAL_MS = 10; + /** * This class includes all the functionality related to interacting with a websocket endpoint * that implements the standard relayer API v0 @@ -21,15 +26,25 @@ export class WebSocketOrderbookChannel implements OrderbookChannel { private _apiEndpointUrl: string; private _client: WebSocket.client; private _connectionIfExists?: WebSocket.connection; + private _heartbeatTimerIfExists?: NodeJS.Timer; private _subscriptionCounter = 0; + private _heartbeatIntervalMs: number; /** * Instantiates a new WebSocketOrderbookChannel instance * @param url The relayer API base WS url you would like to interact with + * @param config The configuration object. Look up the type for the description. * @return An instance of WebSocketOrderbookChannel */ - constructor(url: string) { + constructor(url: string, config?: WebSocketOrderbookChannelConfig) { assert.isUri('url', url); + if (!_.isUndefined(config)) { + assert.doesConformToSchema('config', config, clientSchemas.webSocketOrderbookChannelConfigSchema); + } this._apiEndpointUrl = url; + this._heartbeatIntervalMs = + _.isUndefined(config) || _.isUndefined(config.heartbeatIntervalMs) + ? DEFAULT_HEARTBEAT_INTERVAL_MS + : config.heartbeatIntervalMs; this._client = new WebSocket.client(); } /** @@ -63,7 +78,7 @@ export class WebSocketOrderbookChannel implements OrderbookChannel { connection.on(WebsocketConnectionEventType.Error, wsError => { handler.onError(this, subscriptionOpts, wsError); }); - connection.on(WebsocketConnectionEventType.Close, () => { + connection.on(WebsocketConnectionEventType.Close, (code: number, desc: string) => { handler.onClose(this, subscriptionOpts); }); connection.on(WebsocketConnectionEventType.Message, message => { @@ -80,6 +95,9 @@ export class WebSocketOrderbookChannel implements OrderbookChannel { if (!_.isUndefined(this._connectionIfExists)) { this._connectionIfExists.close(); } + if (!_.isUndefined(this._heartbeatTimerIfExists)) { + clearInterval(this._heartbeatTimerIfExists); + } } private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void) { if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) { @@ -87,6 +105,20 @@ export class WebSocketOrderbookChannel implements OrderbookChannel { } else { this._client.on(WebsocketClientEventType.Connect, connection => { this._connectionIfExists = connection; + if (this._heartbeatIntervalMs >= MINIMUM_HEARTBEAT_INTERVAL_MS) { + this._heartbeatTimerIfExists = setInterval(() => { + connection.ping(''); + }, this._heartbeatIntervalMs); + } else { + callback( + new Error( + `Heartbeat interval is ${ + this._heartbeatIntervalMs + }ms which is less than the required minimum of ${MINIMUM_HEARTBEAT_INTERVAL_MS}ms`, + ), + undefined, + ); + } callback(undefined, this._connectionIfExists); }); this._client.on(WebsocketClientEventType.ConnectFailed, error => { |