Skip to content

Instantly share code, notes, and snippets.

@pladaria
Last active April 22, 2017 10:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pladaria/d5d5e8aa7a31de1a4e4810a055c6c46d to your computer and use it in GitHub Desktop.
Save pladaria/d5d5e8aa7a31de1a4e4810a055c6c46d to your computer and use it in GitHub Desktop.
requirebin sketch
const RWS = require('reconnecting-websocket');
const rws1 = new RWS('wss://echo.websocket.org');
const rws2 = new RWS('wss://echo.websocket.org', undefined);
rws1.onopen = () => console.log('ws1 connected');
rws2.onopen = () => console.log('ws2 connected');
setTimeout(function(){
;require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"reconnecting-websocket":[function(require,module,exports){
"use strict";
var isWebSocket = function (constructor) {
return constructor && constructor.CLOSING === 2;
};
var isGlobalWebSocket = function () {
return typeof WebSocket !== 'undefined' && isWebSocket(WebSocket);
};
var getDefaultOptions = function () { return ({
constructor: isGlobalWebSocket() ? WebSocket : null,
maxReconnectionDelay: 10000,
minReconnectionDelay: 1500,
reconnectionDelayGrowFactor: 1.3,
connectionTimeout: 4000,
maxRetries: Infinity,
debug: false,
}); };
var bypassProperty = function (src, dst, name) {
Object.defineProperty(dst, name, {
get: function () { return src[name]; },
set: function (value) { src[name] = value; },
enumerable: true,
configurable: true,
});
};
var initReconnectionDelay = function (config) {
return (config.minReconnectionDelay + Math.random() * config.minReconnectionDelay);
};
var updateReconnectionDelay = function (config, previousDelay) {
var newDelay = previousDelay * config.reconnectionDelayGrowFactor;
return (newDelay > config.maxReconnectionDelay)
? config.maxReconnectionDelay
: newDelay;
};
var LEVEL_0_EVENTS = ['onopen', 'onclose', 'onmessage', 'onerror'];
var reassignEventListeners = function (ws, oldWs, listeners) {
Object.keys(listeners).forEach(function (type) {
listeners[type].forEach(function (_a) {
var listener = _a[0], options = _a[1];
ws.addEventListener(type, listener, options);
});
});
if (oldWs) {
LEVEL_0_EVENTS.forEach(function (name) { ws[name] = oldWs[name]; });
}
};
var ReconnectingWebsocket = function (url, protocols, options) {
var _this = this;
if (options === void 0) { options = {}; }
var ws;
var connectingTimeout;
var reconnectDelay = 0;
var retriesCount = 0;
var shouldRetry = true;
var savedOnClose = null;
var listeners = {};
// require new to construct
if (!(this instanceof ReconnectingWebsocket)) {
throw new TypeError("Failed to construct 'ReconnectingWebSocket': Please use the 'new' operator");
}
// Set config. Not using `Object.assign` because of IE11
var config = getDefaultOptions();
Object.keys(config)
.filter(function (key) { return options.hasOwnProperty(key); })
.forEach(function (key) { return config[key] = options[key]; });
if (!isWebSocket(config.constructor)) {
throw new TypeError('Invalid WebSocket constructor. Set `options.constructor`');
}
var log = config.debug ? function () {
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i - 0] = arguments[_i];
}
return console.log.apply(console, ['RWS:'].concat(params));
} : function () { };
/**
* Not using dispatchEvent, otherwise we must use a DOM Event object
* Deferred because we want to handle the close event before this
*/
var emitError = function (code, msg) { return setTimeout(function () {
var err = new Error(msg);
err.code = code;
if (Array.isArray(listeners.error)) {
listeners.error.forEach(function (_a) {
var fn = _a[0];
return fn(err);
});
}
if (ws.onerror) {
ws.onerror(err);
}
}, 0); };
var handleClose = function () {
log('close');
retriesCount++;
log('retries count:', retriesCount);
if (retriesCount > config.maxRetries) {
emitError('EHOSTDOWN', 'Too many failed connection attempts');
return;
}
if (!reconnectDelay) {
reconnectDelay = initReconnectionDelay(config);
}
else {
reconnectDelay = updateReconnectionDelay(config, reconnectDelay);
}
log('reconnectDelay:', reconnectDelay);
if (shouldRetry) {
setTimeout(connect, reconnectDelay);
}
};
var connect = function () {
log('connect');
var oldWs = ws;
ws = new config.constructor(url, protocols);
connectingTimeout = setTimeout(function () {
log('timeout');
ws.close();
emitError('ETIMEDOUT', 'Connection timeout');
}, config.connectionTimeout);
log('bypass properties');
for (var key in ws) {
// @todo move to constant
if (['addEventListener', 'removeEventListener', 'close', 'send'].indexOf(key) < 0) {
bypassProperty(ws, _this, key);
}
}
ws.addEventListener('open', function () {
clearTimeout(connectingTimeout);
log('open');
reconnectDelay = initReconnectionDelay(config);
log('reconnectDelay:', reconnectDelay);
retriesCount = 0;
});
ws.addEventListener('close', handleClose);
reassignEventListeners(ws, oldWs, listeners);
// because when closing with fastClose=true, it is saved and set to null to avoid double calls
ws.onclose = ws.onclose || savedOnClose;
savedOnClose = null;
};
log('init');
connect();
this.close = function (code, reason, _a) {
if (code === void 0) { code = 1000; }
if (reason === void 0) { reason = ''; }
var _b = _a === void 0 ? {} : _a, _c = _b.keepClosed, keepClosed = _c === void 0 ? false : _c, _d = _b.fastClose, fastClose = _d === void 0 ? true : _d, _e = _b.delay, delay = _e === void 0 ? 0 : _e;
if (delay) {
reconnectDelay = delay;
}
shouldRetry = !keepClosed;
ws.close(code, reason);
if (fastClose) {
var fakeCloseEvent_1 = {
code: code,
reason: reason,
wasClean: true,
};
// execute close listeners soon with a fake closeEvent
// and remove them from the WS instance so they
// don't get fired on the real close.
handleClose();
ws.removeEventListener('close', handleClose);
// run and remove level2
if (Array.isArray(listeners.close)) {
listeners.close.forEach(function (_a) {
var listener = _a[0], options = _a[1];
listener(fakeCloseEvent_1);
ws.removeEventListener('close', listener, options);
});
}
// run and remove level0
if (ws.onclose) {
savedOnClose = ws.onclose;
ws.onclose(fakeCloseEvent_1);
ws.onclose = null;
}
}
};
this.send = function (data) {
ws.send(data);
};
this.addEventListener = function (type, listener, options) {
if (Array.isArray(listeners[type])) {
if (!listeners[type].some(function (_a) {
var l = _a[0];
return l === listener;
})) {
listeners[type].push([listener, options]);
}
}
else {
listeners[type] = [[listener, options]];
}
ws.addEventListener(type, listener, options);
};
this.removeEventListener = function (type, listener, options) {
if (Array.isArray(listeners[type])) {
listeners[type] = listeners[type].filter(function (_a) {
var l = _a[0];
return l !== listener;
});
}
ws.removeEventListener(type, listener, options);
};
};
module.exports = ReconnectingWebsocket;
},{}]},{},[])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsInJlY29ubmVjdGluZy13ZWJzb2NrZXQiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIlwidXNlIHN0cmljdFwiO1xudmFyIGlzV2ViU29ja2V0ID0gZnVuY3Rpb24gKGNvbnN0cnVjdG9yKSB7XG4gICAgcmV0dXJuIGNvbnN0cnVjdG9yICYmIGNvbnN0cnVjdG9yLkNMT1NJTkcgPT09IDI7XG59O1xudmFyIGlzR2xvYmFsV2ViU29ja2V0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0eXBlb2YgV2ViU29ja2V0ICE9PSAndW5kZWZpbmVkJyAmJiBpc1dlYlNvY2tldChXZWJTb2NrZXQpO1xufTtcbnZhciBnZXREZWZhdWx0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICh7XG4gICAgY29uc3RydWN0b3I6IGlzR2xvYmFsV2ViU29ja2V0KCkgPyBXZWJTb2NrZXQgOiBudWxsLFxuICAgIG1heFJlY29ubmVjdGlvbkRlbGF5OiAxMDAwMCxcbiAgICBtaW5SZWNvbm5lY3Rpb25EZWxheTogMTUwMCxcbiAgICByZWNvbm5lY3Rpb25EZWxheUdyb3dGYWN0b3I6IDEuMyxcbiAgICBjb25uZWN0aW9uVGltZW91dDogNDAwMCxcbiAgICBtYXhSZXRyaWVzOiBJbmZpbml0eSxcbiAgICBkZWJ1ZzogZmFsc2UsXG59KTsgfTtcbnZhciBieXBhc3NQcm9wZXJ0eSA9IGZ1bmN0aW9uIChzcmMsIGRzdCwgbmFtZSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkc3QsIG5hbWUsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBzcmNbbmFtZV07IH0sXG4gICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7IHNyY1tuYW1lXSA9IHZhbHVlOyB9LFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgfSk7XG59O1xudmFyIGluaXRSZWNvbm5lY3Rpb25EZWxheSA9IGZ1bmN0aW9uIChjb25maWcpIHtcbiAgICByZXR1cm4gKGNvbmZpZy5taW5SZWNvbm5lY3Rpb25EZWxheSArIE1hdGgucmFuZG9tKCkgKiBjb25maWcubWluUmVjb25uZWN0aW9uRGVsYXkpO1xufTtcbnZhciB1cGRhdGVSZWNvbm5lY3Rpb25EZWxheSA9IGZ1bmN0aW9uIChjb25maWcsIHByZXZpb3VzRGVsYXkpIHtcbiAgICB2YXIgbmV3RGVsYXkgPSBwcmV2aW91c0RlbGF5ICogY29uZmlnLnJlY29ubmVjdGlvbkRlbGF5R3Jvd0ZhY3RvcjtcbiAgICByZXR1cm4gKG5ld0RlbGF5ID4gY29uZmlnLm1heFJlY29ubmVjdGlvbkRlbGF5KVxuICAgICAgICA/IGNvbmZpZy5tYXhSZWNvbm5lY3Rpb25EZWxheVxuICAgICAgICA6IG5ld0RlbGF5O1xufTtcbnZhciBMRVZFTF8wX0VWRU5UUyA9IFsnb25vcGVuJywgJ29uY2xvc2UnLCAnb25tZXNzYWdlJywgJ29uZXJyb3InXTtcbnZhciByZWFzc2lnbkV2ZW50TGlzdGVuZXJzID0gZnVuY3Rpb24gKHdzLCBvbGRXcywgbGlzdGVuZXJzKSB7XG4gICAgT2JqZWN0LmtleXMobGlzdGVuZXJzKS5mb3JFYWNoKGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgICAgIGxpc3RlbmVyc1t0eXBlXS5mb3JFYWNoKGZ1bmN0aW9uIChfYSkge1xuICAgICAgICAgICAgdmFyIGxpc3RlbmVyID0gX2FbMF0sIG9wdGlvbnMgPSBfYVsxXTtcbiAgICAgICAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICBpZiAob2xkV3MpIHtcbiAgICAgICAgTEVWRUxfMF9FVkVOVFMuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkgeyB3c1tuYW1lXSA9IG9sZFdzW25hbWVdOyB9KTtcbiAgICB9XG59O1xudmFyIFJlY29ubmVjdGluZ1dlYnNvY2tldCA9IGZ1bmN0aW9uICh1cmwsIHByb3RvY29scywgb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkgeyBvcHRpb25zID0ge307IH1cbiAgICB2YXIgd3M7XG4gICAgdmFyIGNvbm5lY3RpbmdUaW1lb3V0O1xuICAgIHZhciByZWNvbm5lY3REZWxheSA9IDA7XG4gICAgdmFyIHJldHJpZXNDb3VudCA9IDA7XG4gICAgdmFyIHNob3VsZFJldHJ5ID0gdHJ1ZTtcbiAgICB2YXIgc2F2ZWRPbkNsb3NlID0gbnVsbDtcbiAgICB2YXIgbGlzdGVuZXJzID0ge307XG4gICAgLy8gcmVxdWlyZSBuZXcgdG8gY29uc3RydWN0XG4gICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJlY29ubmVjdGluZ1dlYnNvY2tldCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZhaWxlZCB0byBjb25zdHJ1Y3QgJ1JlY29ubmVjdGluZ1dlYlNvY2tldCc6IFBsZWFzZSB1c2UgdGhlICduZXcnIG9wZXJhdG9yXCIpO1xuICAgIH1cbiAgICAvLyBTZXQgY29uZmlnLiBOb3QgdXNpbmcgYE9iamVjdC5hc3NpZ25gIGJlY2F1c2Ugb2YgSUUxMVxuICAgIHZhciBjb25maWcgPSBnZXREZWZhdWx0T3B0aW9ucygpO1xuICAgIE9iamVjdC5rZXlzKGNvbmZpZylcbiAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBvcHRpb25zLmhhc093blByb3BlcnR5KGtleSk7IH0pXG4gICAgICAgIC5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGNvbmZpZ1trZXldID0gb3B0aW9uc1trZXldOyB9KTtcbiAgICBpZiAoIWlzV2ViU29ja2V0KGNvbmZpZy5jb25zdHJ1Y3RvcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBXZWJTb2NrZXQgY29uc3RydWN0b3IuIFNldCBgb3B0aW9ucy5jb25zdHJ1Y3RvcmAnKTtcbiAgICB9XG4gICAgdmFyIGxvZyA9IGNvbmZpZy5kZWJ1ZyA/IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBhcmFtcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgcGFyYW1zW19pIC0gMF0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb25zb2xlLmxvZy5hcHBseShjb25zb2xlLCBbJ1JXUzonXS5jb25jYXQocGFyYW1zKSk7XG4gICAgfSA6IGZ1bmN0aW9uICgpIHsgfTtcbiAgICAvKipcbiAgICAgKiBOb3QgdXNpbmcgZGlzcGF0Y2hFdmVudCwgb3RoZXJ3aXNlIHdlIG11c3QgdXNlIGEgRE9NIEV2ZW50IG9iamVjdFxuICAgICAqIERlZmVycmVkIGJlY2F1c2Ugd2Ugd2FudCB0byBoYW5kbGUgdGhlIGNsb3NlIGV2ZW50IGJlZm9yZSB0aGlzXG4gICAgICovXG4gICAgdmFyIGVtaXRFcnJvciA9IGZ1bmN0aW9uIChjb2RlLCBtc2cpIHsgcmV0dXJuIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZXJyID0gbmV3IEVycm9yKG1zZyk7XG4gICAgICAgIGVyci5jb2RlID0gY29kZTtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkobGlzdGVuZXJzLmVycm9yKSkge1xuICAgICAgICAgICAgbGlzdGVuZXJzLmVycm9yLmZvckVhY2goZnVuY3Rpb24gKF9hKSB7XG4gICAgICAgICAgICAgICAgdmFyIGZuID0gX2FbMF07XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZuKGVycik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAod3Mub25lcnJvcikge1xuICAgICAgICAgICAgd3Mub25lcnJvcihlcnIpO1xuICAgICAgICB9XG4gICAgfSwgMCk7IH07XG4gICAgdmFyIGhhbmRsZUNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBsb2coJ2Nsb3NlJyk7XG4gICAgICAgIHJldHJpZXNDb3VudCsrO1xuICAgICAgICBsb2coJ3JldHJpZXMgY291bnQ6JywgcmV0cmllc0NvdW50KTtcbiAgICAgICAgaWYgKHJldHJpZXNDb3VudCA+IGNvbmZpZy5tYXhSZXRyaWVzKSB7XG4gICAgICAgICAgICBlbWl0RXJyb3IoJ0VIT1NURE9XTicsICdUb28gbWFueSBmYWlsZWQgY29ubmVjdGlvbiBhdHRlbXB0cycpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmVjb25uZWN0RGVsYXkpIHtcbiAgICAgICAgICAgIHJlY29ubmVjdERlbGF5ID0gaW5pdFJlY29ubmVjdGlvbkRlbGF5KGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZWNvbm5lY3REZWxheSA9IHVwZGF0ZVJlY29ubmVjdGlvbkRlbGF5KGNvbmZpZywgcmVjb25uZWN0RGVsYXkpO1xuICAgICAgICB9XG4gICAgICAgIGxvZygncmVjb25uZWN0RGVsYXk6JywgcmVjb25uZWN0RGVsYXkpO1xuICAgICAgICBpZiAoc2hvdWxkUmV0cnkpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoY29ubmVjdCwgcmVjb25uZWN0RGVsYXkpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICB2YXIgY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbG9nKCdjb25uZWN0Jyk7XG4gICAgICAgIHZhciBvbGRXcyA9IHdzO1xuICAgICAgICB3cyA9IG5ldyBjb25maWcuY29uc3RydWN0b3IodXJsLCBwcm90b2NvbHMpO1xuICAgICAgICBjb25uZWN0aW5nVGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbG9nKCd0aW1lb3V0Jyk7XG4gICAgICAgICAgICB3cy5jbG9zZSgpO1xuICAgICAgICAgICAgZW1pdEVycm9yKCdFVElNRURPVVQnLCAnQ29ubmVjdGlvbiB0aW1lb3V0Jyk7XG4gICAgICAgIH0sIGNvbmZpZy5jb25uZWN0aW9uVGltZW91dCk7XG4gICAgICAgIGxvZygnYnlwYXNzIHByb3BlcnRpZXMnKTtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIHdzKSB7XG4gICAgICAgICAgICAvLyBAdG9kbyBtb3ZlIHRvIGNvbnN0YW50XG4gICAgICAgICAgICBpZiAoWydhZGRFdmVudExpc3RlbmVyJywgJ3JlbW92ZUV2ZW50TGlzdGVuZXInLCAnY2xvc2UnLCAnc2VuZCddLmluZGV4T2Yoa2V5KSA8IDApIHtcbiAgICAgICAgICAgICAgICBieXBhc3NQcm9wZXJ0eSh3cywgX3RoaXMsIGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgd3MuYWRkRXZlbnRMaXN0ZW5lcignb3BlbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dChjb25uZWN0aW5nVGltZW91dCk7XG4gICAgICAgICAgICBsb2coJ29wZW4nKTtcbiAgICAgICAgICAgIHJlY29ubmVjdERlbGF5ID0gaW5pdFJlY29ubmVjdGlvbkRlbGF5KGNvbmZpZyk7XG4gICAgICAgICAgICBsb2coJ3JlY29ubmVjdERlbGF5OicsIHJlY29ubmVjdERlbGF5KTtcbiAgICAgICAgICAgIHJldHJpZXNDb3VudCA9IDA7XG4gICAgICAgIH0pO1xuICAgICAgICB3cy5hZGRFdmVudExpc3RlbmVyKCdjbG9zZScsIGhhbmRsZUNsb3NlKTtcbiAgICAgICAgcmVhc3NpZ25FdmVudExpc3RlbmVycyh3cywgb2xkV3MsIGxpc3RlbmVycyk7XG4gICAgICAgIC8vIGJlY2F1c2Ugd2hlbiBjbG9zaW5nIHdpdGggZmFzdENsb3NlPXRydWUsIGl0IGlzIHNhdmVkIGFuZCBzZXQgdG8gbnVsbCB0byBhdm9pZCBkb3VibGUgY2FsbHNcbiAgICAgICAgd3Mub25jbG9zZSA9IHdzLm9uY2xvc2UgfHwgc2F2ZWRPbkNsb3NlO1xuICAgICAgICBzYXZlZE9uQ2xvc2UgPSBudWxsO1xuICAgIH07XG4gICAgbG9nKCdpbml0Jyk7XG4gICAgY29ubmVjdCgpO1xuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoY29kZSwgcmVhc29uLCBfYSkge1xuICAgICAgICBpZiAoY29kZSA9PT0gdm9pZCAwKSB7IGNvZGUgPSAxMDAwOyB9XG4gICAgICAgIGlmIChyZWFzb24gPT09IHZvaWQgMCkgeyByZWFzb24gPSAnJzsgfVxuICAgICAgICB2YXIgX2IgPSBfYSA9PT0gdm9pZCAwID8ge30gOiBfYSwgX2MgPSBfYi5rZWVwQ2xvc2VkLCBrZWVwQ2xvc2VkID0gX2MgPT09IHZvaWQgMCA/IGZhbHNlIDogX2MsIF9kID0gX2IuZmFzdENsb3NlLCBmYXN0Q2xvc2UgPSBfZCA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9kLCBfZSA9IF9iLmRlbGF5LCBkZWxheSA9IF9lID09PSB2b2lkIDAgPyAwIDogX2U7XG4gICAgICAgIGlmIChkZWxheSkge1xuICAgICAgICAgICAgcmVjb25uZWN0RGVsYXkgPSBkZWxheTtcbiAgICAgICAgfVxuICAgICAgICBzaG91bGRSZXRyeSA9ICFrZWVwQ2xvc2VkO1xuICAgICAgICB3cy5jbG9zZShjb2RlLCByZWFzb24pO1xuICAgICAgICBpZiAoZmFzdENsb3NlKSB7XG4gICAgICAgICAgICB2YXIgZmFrZUNsb3NlRXZlbnRfMSA9IHtcbiAgICAgICAgICAgICAgICBjb2RlOiBjb2RlLFxuICAgICAgICAgICAgICAgIHJlYXNvbjogcmVhc29uLFxuICAgICAgICAgICAgICAgIHdhc0NsZWFuOiB0cnVlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIGV4ZWN1dGUgY2xvc2UgbGlzdGVuZXJzIHNvb24gd2l0aCBhIGZha2UgY2xvc2VFdmVudFxuICAgICAgICAgICAgLy8gYW5kIHJlbW92ZSB0aGVtIGZyb20gdGhlIFdTIGluc3RhbmNlIHNvIHRoZXlcbiAgICAgICAgICAgIC8vIGRvbid0IGdldCBmaXJlZCBvbiB0aGUgcmVhbCBjbG9zZS5cbiAgICAgICAgICAgIGhhbmRsZUNsb3NlKCk7XG4gICAgICAgICAgICB3cy5yZW1vdmVFdmVudExpc3RlbmVyKCdjbG9zZScsIGhhbmRsZUNsb3NlKTtcbiAgICAgICAgICAgIC8vIHJ1biBhbmQgcmVtb3ZlIGxldmVsMlxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkobGlzdGVuZXJzLmNsb3NlKSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVycy5jbG9zZS5mb3JFYWNoKGZ1bmN0aW9uIChfYSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBfYVswXSwgb3B0aW9ucyA9IF9hWzFdO1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcihmYWtlQ2xvc2VFdmVudF8xKTtcbiAgICAgICAgICAgICAgICAgICAgd3MucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xvc2UnLCBsaXN0ZW5lciwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBydW4gYW5kIHJlbW92ZSBsZXZlbDBcbiAgICAgICAgICAgIGlmICh3cy5vbmNsb3NlKSB7XG4gICAgICAgICAgICAgICAgc2F2ZWRPbkNsb3NlID0gd3Mub25jbG9zZTtcbiAgICAgICAgICAgICAgICB3cy5vbmNsb3NlKGZha2VDbG9zZUV2ZW50XzEpO1xuICAgICAgICAgICAgICAgIHdzLm9uY2xvc2UgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB3cy5zZW5kKGRhdGEpO1xuICAgIH07XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGxpc3RlbmVyc1t0eXBlXSkpIHtcbiAgICAgICAgICAgIGlmICghbGlzdGVuZXJzW3R5cGVdLnNvbWUoZnVuY3Rpb24gKF9hKSB7XG4gICAgICAgICAgICAgICAgdmFyIGwgPSBfYVswXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbCA9PT0gbGlzdGVuZXI7XG4gICAgICAgICAgICB9KSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1t0eXBlXS5wdXNoKFtsaXN0ZW5lciwgb3B0aW9uc10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGlzdGVuZXJzW3R5cGVdID0gW1tsaXN0ZW5lciwgb3B0aW9uc11dO1xuICAgICAgICB9XG4gICAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgIH07XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGxpc3RlbmVyc1t0eXBlXSkpIHtcbiAgICAgICAgICAgIGxpc3RlbmVyc1t0eXBlXSA9IGxpc3RlbmVyc1t0eXBlXS5maWx0ZXIoZnVuY3Rpb24gKF9hKSB7XG4gICAgICAgICAgICAgICAgdmFyIGwgPSBfYVswXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbCAhPT0gbGlzdGVuZXI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB3cy5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKTtcbiAgICB9O1xufTtcbm1vZHVsZS5leHBvcnRzID0gUmVjb25uZWN0aW5nV2Vic29ja2V0O1xuIl19
const RWS = require('reconnecting-websocket');
const rws1 = new RWS('wss://echo.websocket.org');
const rws2 = new RWS('wss://echo.websocket.org', undefined);
rws1.onopen = () => console.log('ws1 connected');
rws2.onopen = () => console.log('ws2 connected');
;}, 0)
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"reconnecting-websocket": "3.0.3"
}
}
<!-- contents of this file will be placed inside the <body> -->
<!-- contents of this file will be placed inside the <head> -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment