UNPKG

@akala/json-rpc-ws

Version:

json-rpc websocket transport

116 lines 3.77 kB
import { Base } from './base.js'; import debug from 'debug'; const logger = debug('akala:json-rpc-ws'); import { SocketProtocolAdapter } from '@akala/core'; /** * json-rpc-ws connection * * @constructor * @param {Socket} socket - web socket for this connection * @param {Object} parent - parent that controls this connection */ export class JsonNDRpcSocketAdapter extends SocketProtocolAdapter { constructor(socket) { const accumulator = []; super({ receive: (data) => { if (typeof (data) !== 'string') data = data.toString('utf8'); let messages = data.split('\n'); if (messages.length == 1) { accumulator.push(messages[0]); return []; } if (accumulator.length) messages = accumulator.concat(messages); messages = messages.filter(d => d); return messages.map(data => JSON.parse(data)); }, send: (data) => JSON.stringify(data) + '\n', }, socket); } } export default class Client extends Base { socketConstructor; options; constructor(socketConstructor, options) { super('client'); this.socketConstructor = socketConstructor; this.options = options; logger('new Client'); } socket; /** * Connect to a json-rpc-ws server * * @param {String} address - url to connect to i.e. `ws://foo.com/`. * @param {function} callback - optional callback to call once socket is connected * @public */ connect(address, callback) { logger('Client connect %s', address); if (this.isConnected()) throw new Error('Already connected'); let opened = false; const socket = this.socket = this.socketConstructor(address, this.options); socket.once('open', () => { // The client connected handler runs scoped as the socket so we can pass // it into our connected method like thisk this.connected(socket); opened = true; if (callback) callback.call(this); }); if (callback) this.socket.once('error', function socketError(err) { if (!opened) { callback.call(self, err); } }); } /** * Test whether we have a connection or not * * @returns {Boolean} whether or not we have a connection * @public */ isConnected() { return Object.keys(this.connections).length !== 0; } /** * Return the current connection (there can be only one) * * @returns {Object} current connection * @public */ getConnection() { const ids = Object.keys(this.connections); return this.connections[ids[0]]; } /** * Close the current connection */ disconnect() { if (!this.isConnected()) throw new Error('Not connected'); const connection = this.getConnection(); return connection.hangup(); } /** * Send a method request * * @param {String} method - name of method * @param {Array} params - optional parameters for method * @param {function} callback - optional reply handler * @public * @todo allow for empty params aka arguments.length === 2 */ send(method, params, callback) { logger('send %s', method); if (!this.isConnected()) throw new Error('Not connected'); const connection = this.getConnection(); connection.sendMethod(method, params, callback); } } //# sourceMappingURL=shared-client.js.map