Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
setTimeout(() => {
// Skip reconnect when client is connecting.
// https://github.com/websockets/ws/blob/7.2.1/lib/websocket.js#L365
if (this._client && this._client.readyState === WS.CONNECTING) {
return
}
if (this._reconnectCurrentAttempts < this._reconnectMaxAttempts) {
this._reconnectCurrentAttempts++
this._clearBinding()
if (this._client) {
// In reconnect, we want to close the connection immediately,
// because recoonect is necessary when some problems occur.
this._client.terminate()
}
// Call connect methods
console.log('Reconnecting')
this._client = this._connect(this.url, this.stream, this._accessToken, this.headers, this.proxyConfig)
this._bindSocket(this._client)
}
private _checkAlive(timestamp: Moment) {
const now: Moment = moment()
// Block multiple calling, if multiple pong event occur.
// It the duration is less than interval, through ping.
if (now.diff(timestamp) > this._heartbeatInterval - 1000 && !this._connectionClosed) {
// Skip ping when client is connecting.
// https://github.com/websockets/ws/blob/7.2.1/lib/websocket.js#L289
if (this._client && this._client.readyState !== WS.CONNECTING) {
this._pongWaiting = true
this._client.ping('')
setTimeout(() => {
if (this._pongWaiting) {
this._pongWaiting = false
this._reconnect()
}
}, 10000)
}
}
}
}
)
}, this._config.connectionTimeout)
if (!this._url) {
reject(
new ConnectionError(
'Cannot connect because no server was specified'
)
)
}
const resolve = () => {
this._startHeartbeatInterval()
_resolve()
}
if (this._state === WebSocket.OPEN) {
resolve()
} else if (this._state === WebSocket.CONNECTING) {
this._ws.once('open', () => resolve)
} else {
this._ws = this._createWebSocket()
// when an error causes the connection to close, the close event
// should still be emitted; the "ws" documentation says: "The close
// event is also emitted when then underlying net.Socket closes the
// connection (end or close)."
// In case if there is connection error (say, server is not responding)
// we must return this error to connection's caller. After successful
// opening, we will forward all errors to main api object.
this._onOpenErrorBound = this._onOpenError.bind(this, reject)
this._ws.once('error', this._onOpenErrorBound)
this._ws.on('message', this._onMessage.bind(this))
// in browser close event can came before open event, so we must
// resolve connect's promise after reconnect in that case.
// after open event we will rebound _onUnexpectedCloseBound
teardown() {
if (this.subprocess && this.subprocess.isRunning()) {
this.subprocess.stop();
}
this.updateStatus(ProcessStatus.Closed);
if (this.ws && [Websocket.OPEN, Websocket.CONNECTING].includes(this.ws.readyState)) {
try {
this.ws.close();
} catch (err) {
console.warn(err);
}
}
this.dataSubscription = NO_OP;
this.statusSubscription = NO_OP;
}
close() {
debug('[%s] broker client explicitly close connection', this.eventName);
resetPing(this);
if (this.client.connected.promise.isFulfilled()) {
this.client.connected = getDeferredPromise();
}
if (!this.client.socket) {
this.kuzzle.log.error(`[${this.eventName}] Unable to close socket: socket not available`);
return false;
}
if (this.client.socket.readyState === WS.OPEN || this.client.socket.readyState === WS.CONNECTING) {
this.client.socket.close();
}
this.client.socket = null;
}
!this.ws ||
!this.ws.readyState ||
this.ws.readyState === WebSocket.CLOSED
) {
ethereumNodeRemoteLog.warn(
`Remote websocket connection not open, attempting to reconnect and retry ${method}...`
);
return new Promise(resolve => {
this.start().then(() => {
resolve(this.send(method, params, retry));
});
});
}
if (this.ws.readyState !== WebSocket.OPEN) {
if (this.ws.readyState === WebSocket.CONNECTING) {
ethereumNodeRemoteLog.error(
`Can't send method ${method} because remote WebSocket is connecting`
);
} else if (this.ws.readyState === WebSocket.CLOSING) {
ethereumNodeRemoteLog.error(
`Can't send method ${method} because remote WebSocket is closing`
);
} else if (this.ws.readyState === WebSocket.CLOSED) {
ethereumNodeRemoteLog.error(
`Can't send method ${method} because remote WebSocket is closed`
);
}
if (!retry) {
ethereumNodeRemoteLog.error(`Retrying ${method} in 1.5s...`);
return new Promise(resolve => {
setTimeout(() => {
/**
* Adapts the nodejs websocket lib WebSocket-Node to the WebSocket client API.
* See: http://dev.w3.org/html5/websockets/#the-websocket-interface
*
*/
import ws from "ws";
interface KeyChain {
tlsCert: any;
tlsKey: any;
tlsCa: any;
checkServerIdentity: any;
}
class WebSocketNode extends ws {
public static CONNECTING = ws.CONNECTING;
public static OPEN = ws.OPEN;
public static CLOSING = ws.CLOSING;
public static CLOSED = ws.CLOSED;
public constructor(remoteUrl: string, keychain: KeyChain, useUnencryptedTls: boolean) {
const clientOptions: ws.ClientOptions = {};
if (keychain) {
clientOptions.cert = keychain.tlsCert;
clientOptions.key = keychain.tlsKey;
clientOptions.ca = keychain.tlsCa;
clientOptions.rejectUnauthorized = true;
clientOptions.checkServerIdentity = keychain.checkServerIdentity;
}
if (useUnencryptedTls) {
clientOptions.ciphers = "eNULL:@SECLEVEL=0";
const check = (k) => {
if (k <= 0)
reject(new Error("failed to await WebSocket ready-state OPEN"))
else if (this._ws.readyState === WebSocket.CLOSED)
reject(new Error("failed to send to WebSocket, already in ready-state CLOSED"))
else if (this._ws.readyState === WebSocket.CLOSING)
reject(new Error("failed to send to WebSocket, already in ready-state CLOSING"))
else if (this._ws.readyState === WebSocket.CONNECTING)
setTimeout(() => check(k - 1), 100)
else
resolve()
}
check(100)
var constructMessage = function (hubName, functionName, args) {
if(thisApi.wsClient === undefined) {
throw Error('ws not connected');
}
args = Array.prototype.slice.call(args);
var id = messageID++,
body = {'hub': hubName, 'function': functionName, 'args': args, 'ID': id};
if(thisApi.wsClient.readyState === WebSocket.CONNECTING) {
messagesBeforeOpen.push(JSON.stringify(body));
} else if (thisApi.wsClient.readyState !== WebSocket.OPEN) {
window.setTimeout(function () {
var f = returnFunctions[id];
if (f !== undefined && f.onError !== undefined) {
f.onError('webSocket not connected');
}
}, 0);
return {done: getReturnFunction(id, {hubName: hubName, functionName: functionName, args: args})};
}
else {
thisApi.wsClient.send(JSON.stringify(body));
}
return getReturnFunction(id, {hubName: hubName, functionName: functionName, args: args});
};
public close(): void {
if (this.webSocket && (this.webSocket.readyState === WebSocket.OPEN || this.webSocket.readyState === WebSocket.CONNECTING)) {
this.webSocket.close();
}
}