* Connect to WebSocket API for bidirectional JSON-RPC communication * @param {string} connectionId - unique identifier for this connection * @param {function} messageHandler - callback for handling incoming messages/events * @param {function} reconnect - reconnect callback * @ret
(connectionId: string, messageHandler: Callback, reconnect?: Callback)
| 1555 | * @return {WebSocket} - WebSocket connection |
| 1556 | */ |
| 1557 | connectWsApi(connectionId: string, messageHandler: Callback, reconnect?: Callback) { |
| 1558 | const httpsproxy = this.getHttpsProxy(); |
| 1559 | let socksproxy = this.getSocksProxy(); |
| 1560 | let ws: WebSocket = undefined; |
| 1561 | |
| 1562 | if (socksproxy) { |
| 1563 | socksproxy = this.proxyReplacewithIp(socksproxy); |
| 1564 | if (this.Options.verbose) this.Options.log('WebSocket API: using socks proxy server ' + socksproxy); |
| 1565 | const agent = new SocksProxyAgent({ |
| 1566 | protocol: this.parseProxy(socksproxy)[0], |
| 1567 | host: this.parseProxy(socksproxy)[1], |
| 1568 | port: this.parseProxy(socksproxy)[2] |
| 1569 | }); |
| 1570 | ws = new WebSocket(this.getWsApiUrl(), { agent: agent }); |
| 1571 | } else if (httpsproxy) { |
| 1572 | const config = url.parse(httpsproxy); |
| 1573 | const agent = new HttpsProxyAgent(config); |
| 1574 | if (this.Options.verbose) this.Options.log('WebSocket API: using proxy server ' + agent); |
| 1575 | ws = new WebSocket(this.getWsApiUrl(), { agent: agent }); |
| 1576 | } else { |
| 1577 | ws = new WebSocket(this.getWsApiUrl()); |
| 1578 | } |
| 1579 | |
| 1580 | (ws as any).reconnect = this.Options.reconnect; |
| 1581 | (ws as any).connectionId = connectionId; |
| 1582 | (ws as any).isAlive = false; |
| 1583 | |
| 1584 | ws.on('open', () => { |
| 1585 | if (this.Options.verbose) this.Options.log('WebSocket API: Connected to ' + this.getWsApiUrl()); |
| 1586 | (ws as any).isAlive = true; |
| 1587 | }); |
| 1588 | ws.on('pong', () => { (ws as any).isAlive = true; }); |
| 1589 | ws.on('error', (err) => { |
| 1590 | this.Options.log('WebSocket API error: ' + (ws as any).connectionId + ' error: ' + err.message); |
| 1591 | }); |
| 1592 | ws.on('close', (code, reason) => { |
| 1593 | if (this.Options.verbose) this.Options.log('WebSocket API closed: ' + (ws as any).connectionId + |
| 1594 | (code ? ' (' + code + ')' : '') + |
| 1595 | (reason ? ' ' + reason : '')); |
| 1596 | delete this.wsApiConnections[connectionId]; |
| 1597 | if ((ws as any).reconnect && typeof reconnect === 'function') { |
| 1598 | if (this.Options.verbose) this.Options.log('WebSocket API reconnecting: ' + connectionId); |
| 1599 | reconnect(); |
| 1600 | } |
| 1601 | }); |
| 1602 | ws.on('message', data => { |
| 1603 | try { |
| 1604 | if (this.Options.verbose) this.Options.log('WebSocket API data:', data); |
| 1605 | const message = JSONbig.parse(data as any); |
| 1606 | |
| 1607 | // Handle JSON-RPC responses |
| 1608 | if (message.id && this.wsApiPendingRequests[message.id]) { |
| 1609 | const pending = this.wsApiPendingRequests[message.id]; |
| 1610 | |
| 1611 | if (message.status === 200) { |
| 1612 | pending.resolve(message.result); |
| 1613 | } else { |
| 1614 | pending.reject(new Error(`WebSocket API error: ${message.error?.msg || 'Unknown error'}`)); |
no test coverage detected