PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/rpc-websockets/dist/lib
Просмотр файла: client.cjs
/**
* "Client" wraps "ws" or a browser-implemented "WebSocket" library
* according to the environment providing JSON RPC 2.0 support on top.
* @module Client
*/
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// @ts-ignore
const eventemitter3_1 = require("eventemitter3");
const utils_cjs_1 = require("./utils.cjs");
class CommonClient extends eventemitter3_1.EventEmitter {
address;
rpc_id;
queue;
options;
autoconnect;
ready;
reconnect;
reconnect_timer_id;
reconnect_interval;
max_reconnects;
rest_options;
current_reconnects;
generate_request_id;
socket;
webSocketFactory;
dataPack;
/**
* Instantiate a Client class.
* @constructor
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket
* @param {String} address - url to a websocket server
* @param {Object} options - ws options object with reconnect parameters
* @param {Function} generate_request_id - custom generation request Id
* @param {DataPack} dataPack - data pack contains encoder and decoder
* @return {CommonClient}
*/
constructor(webSocketFactory, address = "ws://localhost:8080", { autoconnect = true, reconnect = true, reconnect_interval = 1000, max_reconnects = 5, ...rest_options } = {}, generate_request_id, dataPack) {
super();
this.webSocketFactory = webSocketFactory;
this.queue = {};
this.rpc_id = 0;
this.address = address;
this.autoconnect = autoconnect;
this.ready = false;
this.reconnect = reconnect;
this.reconnect_timer_id = undefined;
this.reconnect_interval = reconnect_interval;
this.max_reconnects = max_reconnects;
this.rest_options = rest_options;
this.current_reconnects = 0;
this.generate_request_id = generate_request_id || (() => ++this.rpc_id);
if (!dataPack)
this.dataPack = new utils_cjs_1.DefaultDataPack();
else
this.dataPack = dataPack;
if (this.autoconnect)
this._connect(this.address, {
autoconnect: this.autoconnect,
reconnect: this.reconnect,
reconnect_interval: this.reconnect_interval,
max_reconnects: this.max_reconnects,
...this.rest_options
});
}
/**
* Connects to a defined server if not connected already.
* @method
* @return {Undefined}
*/
connect() {
if (this.socket)
return;
this._connect(this.address, {
autoconnect: this.autoconnect,
reconnect: this.reconnect,
reconnect_interval: this.reconnect_interval,
max_reconnects: this.max_reconnects,
...this.rest_options
});
}
/**
* Calls a registered RPC method on server.
* @method
* @param {String} method - RPC method name
* @param {Object|Array} params - optional method parameters
* @param {Number} timeout - RPC reply timeout value
* @param {Object} ws_opts - options passed to ws
* @return {Promise}
*/
call(method, params, timeout, ws_opts) {
if (!ws_opts && "object" === typeof timeout) {
ws_opts = timeout;
timeout = null;
}
return new Promise((resolve, reject) => {
if (!this.ready)
return reject(new Error("socket not ready"));
const rpc_id = this.generate_request_id(method, params);
const message = {
jsonrpc: "2.0",
method: method,
params: params || undefined,
id: rpc_id
};
this.socket.send(this.dataPack.encode(message), ws_opts, (error) => {
if (error)
return reject(error);
this.queue[rpc_id] = { promise: [resolve, reject] };
if (timeout) {
this.queue[rpc_id].timeout = setTimeout(() => {
delete this.queue[rpc_id];
reject(new Error("reply timeout"));
}, timeout);
}
});
});
}
/**
* Logins with the other side of the connection.
* @method
* @param {Object} params - Login credentials object
* @return {Promise}
*/
async login(params) {
const resp = await this.call("rpc.login", params);
if (!resp)
throw new Error("authentication failed");
return resp;
}
/**
* Fetches a list of client's methods registered on server.
* @method
* @return {Array}
*/
async listMethods() {
return await this.call("__listMethods");
}
/**
* Sends a JSON-RPC 2.0 notification to server.
* @method
* @param {String} method - RPC method name
* @param {Object} params - optional method parameters
* @return {Promise}
*/
notify(method, params) {
return new Promise((resolve, reject) => {
if (!this.ready)
return reject(new Error("socket not ready"));
const message = {
jsonrpc: "2.0",
method: method,
params
};
this.socket.send(this.dataPack.encode(message), (error) => {
if (error)
return reject(error);
resolve();
});
});
}
/**
* Subscribes for a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
async subscribe(event) {
if (typeof event === "string")
event = [event];
const result = await this.call("rpc.on", event);
if (typeof event === "string" && result[event] !== "ok")
throw new Error("Failed subscribing to an event '" + event + "' with: " + result[event]);
return result;
}
/**
* Unsubscribes from a defined event.
* @method
* @param {String|Array} event - event name
* @return {Undefined}
* @throws {Error}
*/
async unsubscribe(event) {
if (typeof event === "string")
event = [event];
const result = await this.call("rpc.off", event);
if (typeof event === "string" && result[event] !== "ok")
throw new Error("Failed unsubscribing from an event with: " + result);
return result;
}
/**
* Closes a WebSocket connection gracefully.
* @method
* @param {Number} code - socket close code
* @param {String} data - optional data to be sent before closing
* @return {Undefined}
*/
close(code, data) {
this.socket.close(code || 1000, data);
}
/**
* Enable / disable automatic reconnection.
* @method
* @param {Boolean} reconnect - enable / disable reconnection
* @return {Undefined}
*/
setAutoReconnect(reconnect) {
this.reconnect = reconnect;
}
/**
* Set the interval between reconnection attempts.
* @method
* @param {Number} interval - reconnection interval in milliseconds
* @return {Undefined}
*/
setReconnectInterval(interval) {
this.reconnect_interval = interval;
}
/**
* Set the maximum number of reconnection attempts.
* @method
* @param {Number} max_reconnects - maximum reconnection attempts
* @return {Undefined}
*/
setMaxReconnects(max_reconnects) {
this.max_reconnects = max_reconnects;
}
/**
* Connection/Message handler.
* @method
* @private
* @param {String} address - WebSocket API address
* @param {Object} options - ws options object
* @return {Undefined}
*/
_connect(address, options) {
clearTimeout(this.reconnect_timer_id);
this.socket = this.webSocketFactory(address, options);
this.socket.addEventListener("open", () => {
this.ready = true;
this.emit("open");
this.current_reconnects = 0;
});
this.socket.addEventListener("message", ({ data: message }) => {
if (message instanceof ArrayBuffer)
message = Buffer.from(message).toString();
try {
message = this.dataPack.decode(message);
}
catch (error) {
return;
}
// check if any listeners are attached and forward event
if (message.notification && this.listeners(message.notification).length) {
if (!Object.keys(message.params).length)
return this.emit(message.notification);
const args = [message.notification];
if (message.params.constructor === Object)
args.push(message.params);
else
// using for-loop instead of unshift/spread because performance is better
for (let i = 0; i < message.params.length; i++)
args.push(message.params[i]);
// run as microtask so that pending queue messages are resolved first
// eslint-disable-next-line prefer-spread
return Promise.resolve().then(() => { this.emit.apply(this, args); });
}
if (!this.queue[message.id]) {
// general JSON RPC 2.0 events
if (message.method) {
// run as microtask so that pending queue messages are resolved first
return Promise.resolve().then(() => {
this.emit(message.method, message?.params);
});
}
return;
}
// reject early since server's response is invalid
if ("error" in message === "result" in message)
this.queue[message.id].promise[1](new Error("Server response malformed. Response must include either \"result\"" +
" or \"error\", but not both."));
if (this.queue[message.id].timeout)
clearTimeout(this.queue[message.id].timeout);
if (message.error)
this.queue[message.id].promise[1](message.error);
else
this.queue[message.id].promise[0](message.result);
delete this.queue[message.id];
});
this.socket.addEventListener("error", (error) => this.emit("error", error));
this.socket.addEventListener("close", ({ code, reason }) => {
if (this.ready) // Delay close event until internal state is updated
setTimeout(() => this.emit("close", code, reason), 0);
this.ready = false;
this.socket = undefined;
if (code === 1000)
return;
this.current_reconnects++;
if (this.reconnect && ((this.max_reconnects > this.current_reconnects) ||
this.max_reconnects === 0))
this.reconnect_timer_id = setTimeout(() => this._connect(address, options), this.reconnect_interval);
});
}
}
exports.default = CommonClient;
Выполнить команду
Для локальной разработки. Не используйте в интернете!