nxt-aws-client
Advanced tools
| import { IClientConfig } from '../config'; | ||
| import { IOfferPredictRequest, IOfferPredictResponse } from '../domain/predict'; | ||
| import { ILogger } from '../logger'; | ||
| import * as WebSocket from 'ws'; | ||
| export interface ISocketClientOptions { | ||
@@ -11,3 +10,3 @@ logger: ILogger; | ||
| private options; | ||
| readonly client: WebSocket; | ||
| private client; | ||
| private readonly requestsBus; | ||
@@ -18,2 +17,3 @@ private id; | ||
| private sendRequest; | ||
| private createClient; | ||
| } |
+71
-50
@@ -6,2 +6,3 @@ "use strict"; | ||
| const events_1 = require("events"); | ||
| const PING_INTERVAL = 20000; | ||
| class SocketClient { | ||
@@ -15,13 +16,66 @@ constructor(config, options) { | ||
| this.requestsBus.setMaxListeners(0); | ||
| this.client = new WebSocket(config.socket.url, { | ||
| this.createClient(); | ||
| } | ||
| async predictOffer(request) { | ||
| return await this.sendRequest(api_1.EEventRoute.PredictOffer, request); | ||
| } | ||
| async sendRequest(route, payload) { | ||
| const request = { | ||
| route, | ||
| payload, | ||
| id: ++this.id, | ||
| }; | ||
| return await new Promise((resolve, reject) => { | ||
| let timeoutId; | ||
| const handler = (response) => { | ||
| if (response.id !== request.id) { | ||
| return; | ||
| } | ||
| clearTimeout(timeoutId); | ||
| this.requestsBus.removeListener('event', handler); | ||
| if (response.error) { | ||
| reject(new Error(response.error)); | ||
| return; | ||
| } | ||
| resolve(response.payload); | ||
| }; | ||
| timeoutId = setTimeout(() => { | ||
| this.requestsBus.removeListener('event', handler); | ||
| reject(new Error('Request timeout.')); | ||
| }, 5 * 1000); | ||
| this.requestsBus.on('event', handler); | ||
| this.client.send(JSON.stringify(request), (err) => !err || reject(err)); | ||
| }); | ||
| } | ||
| createClient() { | ||
| if (this.client) { | ||
| this.client.removeAllListeners(); | ||
| try { | ||
| this.client.terminate(); | ||
| } | ||
| catch (error) { } | ||
| } | ||
| this.id = 0; | ||
| this.client = new WebSocket(this.config.socket.url, { | ||
| headers: { | ||
| 'x-api-key': config.auth, | ||
| 'x-api-key': this.config.auth, | ||
| }, | ||
| }); | ||
| this.client.on('error', error => this.options.logger.error({ error }, 'Socket error.')); | ||
| this.client.on('close', (code, reason) => this.options.logger.debug({ code, reason }, 'Socket closed.')); | ||
| this.client.on('unexpected-response', (req, res) => this.options.logger.debug({ code: res.statusCode, body: res.read(), status: res.statusMessage }, 'Unexpected socket response.')); | ||
| let pongTimeout; | ||
| this.client.on('close', (code, reason) => { | ||
| this.options.logger.debug({ code, reason }, 'Socket closed.'); | ||
| this.createClient(); | ||
| }); | ||
| this.client.on('unexpected-response', (req, res) => { | ||
| this.options.logger.debug({ | ||
| code: res.statusCode, | ||
| body: res.read(), | ||
| status: res.statusMessage, | ||
| }, 'Unexpected socket response.'); | ||
| }); | ||
| let pingTimeout, pongTimeout; | ||
| const startPing = () => { | ||
| setTimeout(() => { | ||
| clearTimeout(pingTimeout); | ||
| clearTimeout(pongTimeout); | ||
| pingTimeout = setTimeout(() => { | ||
| try { | ||
@@ -34,17 +88,14 @@ this.client.ping(); | ||
| } | ||
| clearTimeout(pongTimeout); | ||
| pongTimeout = setTimeout(() => { | ||
| console.error('WS pong timeout.'); | ||
| try { | ||
| this.client.terminate(); | ||
| } | ||
| catch (error) { | ||
| console.error('WS terminate error.', error); | ||
| } | ||
| return startPing(); | ||
| }, 5000); | ||
| }, 20000); | ||
| }, PING_INTERVAL); | ||
| pongTimeout = setTimeout(() => { | ||
| console.error('WS pong timeout.'); | ||
| try { | ||
| this.client.terminate(); | ||
| } | ||
| catch (error) { | ||
| console.error('WS terminate error.', error); | ||
| } | ||
| }, PING_INTERVAL + 5000); | ||
| }; | ||
| const onPong = () => { | ||
| clearTimeout(pongTimeout); | ||
| startPing(); | ||
@@ -55,2 +106,3 @@ }; | ||
| this.client.on('close', () => { | ||
| clearTimeout(pingTimeout); | ||
| clearTimeout(pongTimeout); | ||
@@ -72,34 +124,3 @@ }); | ||
| } | ||
| async predictOffer(request) { | ||
| return await this.sendRequest(api_1.EEventRoute.PredictOffer, request); | ||
| } | ||
| async sendRequest(route, payload) { | ||
| const request = { | ||
| route, | ||
| payload, | ||
| id: ++this.id, | ||
| }; | ||
| return await new Promise((resolve, reject) => { | ||
| let timeoutId; | ||
| const handler = (response) => { | ||
| if (response.id !== request.id) { | ||
| return; | ||
| } | ||
| clearTimeout(timeoutId); | ||
| this.requestsBus.removeListener('event', handler); | ||
| if (response.error) { | ||
| reject(new Error(response.error)); | ||
| return; | ||
| } | ||
| resolve(response.payload); | ||
| }; | ||
| timeoutId = setTimeout(() => { | ||
| this.requestsBus.removeListener('event', handler); | ||
| reject(new Error('Request timeout.')); | ||
| }, 5 * 1000); | ||
| this.requestsBus.on('event', handler); | ||
| this.client.send(JSON.stringify(request), (err) => !err || reject(err)); | ||
| }); | ||
| } | ||
| } | ||
| exports.SocketClient = SocketClient; |
+1
-1
| { | ||
| "name": "nxt-aws-client", | ||
| "version": "1.1.1", | ||
| "version": "1.2.0", | ||
| "main": "./dist/index.js", | ||
@@ -5,0 +5,0 @@ "types": "./dist/index.d.ts", |
22880
1.95%775
2.79%