@webex/calling 3.12.0-mobius-socket.18 → 3.12.0-mobius-socket.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CallingClient/utils/request.js +6 -3
- package/dist/CallingClient/utils/request.js.map +1 -1
- package/dist/CallingClient/utils/request.test.js +2 -2
- package/dist/CallingClient/utils/request.test.js.map +1 -1
- package/dist/CallingClient/utils/types.js.map +1 -1
- package/dist/mobius-socket/config.js +7 -44
- package/dist/mobius-socket/config.js.map +1 -1
- package/dist/mobius-socket/errors.js +25 -21
- package/dist/mobius-socket/errors.js.map +1 -1
- package/dist/mobius-socket/index.js +0 -44
- package/dist/mobius-socket/index.js.map +1 -1
- package/dist/mobius-socket/mobius-socket-events.test.js +20 -48
- package/dist/mobius-socket/mobius-socket-events.test.js.map +1 -1
- package/dist/mobius-socket/mobius-socket.js +301 -701
- package/dist/mobius-socket/mobius-socket.js.map +1 -1
- package/dist/mobius-socket/mobius-socket.test.js +435 -718
- package/dist/mobius-socket/mobius-socket.test.js.map +1 -1
- package/dist/mobius-socket/socket/socket-base.js +70 -78
- package/dist/mobius-socket/socket/socket-base.js.map +1 -1
- package/dist/mobius-socket/socket.test.js +36 -61
- package/dist/mobius-socket/socket.test.js.map +1 -1
- package/dist/module/CallingClient/utils/request.js +3 -2
- package/dist/module/mobius-socket/config.js +7 -10
- package/dist/module/mobius-socket/errors.js +17 -0
- package/dist/module/mobius-socket/index.js +0 -3
- package/dist/module/mobius-socket/mobius-socket.js +211 -398
- package/dist/module/mobius-socket/socket/socket-base.js +64 -69
- package/dist/types/CallingClient/utils/request.d.ts.map +1 -1
- package/dist/types/CallingClient/utils/types.d.ts +1 -1
- package/dist/types/CallingClient/utils/types.d.ts.map +1 -1
- package/dist/types/mobius-socket/config.d.ts +7 -8
- package/dist/types/mobius-socket/config.d.ts.map +1 -1
- package/dist/types/mobius-socket/errors.d.ts +7 -0
- package/dist/types/mobius-socket/errors.d.ts.map +1 -1
- package/dist/types/mobius-socket/index.d.ts +1 -5
- package/dist/types/mobius-socket/index.d.ts.map +1 -1
- package/dist/types/mobius-socket/mobius-socket.d.ts +20 -35
- package/dist/types/mobius-socket/mobius-socket.d.ts.map +1 -1
- package/dist/types/mobius-socket/socket/socket-base.d.ts +10 -10
- package/dist/types/mobius-socket/socket/socket-base.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
|
|
4
|
-
var
|
|
5
|
-
var _Symbol = require("@babel/runtime-corejs2/core-js/symbol");
|
|
6
|
-
var _Symbol$iterator = require("@babel/runtime-corejs2/core-js/symbol/iterator");
|
|
7
|
-
var _Array$isArray2 = require("@babel/runtime-corejs2/core-js/array/is-array");
|
|
8
|
-
var _Object$keys2 = require("@babel/runtime-corejs2/core-js/object/keys");
|
|
4
|
+
var _Object$keys = require("@babel/runtime-corejs2/core-js/object/keys");
|
|
9
5
|
var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
|
|
10
6
|
var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
|
|
11
7
|
var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
|
|
@@ -17,11 +13,10 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
17
13
|
});
|
|
18
14
|
exports.default = void 0;
|
|
19
15
|
var _map = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/map"));
|
|
20
|
-
var _now = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/date/now"));
|
|
21
|
-
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
|
|
22
16
|
var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
|
|
17
|
+
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
|
|
23
18
|
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
24
|
-
var
|
|
19
|
+
var _now = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/date/now"));
|
|
25
20
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
26
21
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
|
|
27
22
|
var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/typeof"));
|
|
@@ -31,17 +26,12 @@ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime
|
|
|
31
26
|
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
|
|
32
27
|
var _get2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/get"));
|
|
33
28
|
var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
|
|
34
|
-
var _set2 = _interopRequireDefault(require("lodash/set"));
|
|
35
|
-
var _camelCase2 = _interopRequireDefault(require("lodash/camelCase"));
|
|
36
29
|
var _events = require("events");
|
|
37
30
|
var _backoff = _interopRequireDefault(require("backoff"));
|
|
38
31
|
var _socket = _interopRequireDefault(require("./socket"));
|
|
39
32
|
var _errors = require("./errors");
|
|
40
|
-
function ownKeys(e, r) { var t = _Object$
|
|
33
|
+
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
41
34
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
42
|
-
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof _Symbol && r[_Symbol$iterator] || r["@@iterator"]; if (!t) { if (_Array$isArray2(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
43
|
-
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? _Array$from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
44
|
-
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
45
35
|
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
46
36
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
47
37
|
function _superPropGet(t, o, e, r) { var p = (0, _get2.default)((0, _getPrototypeOf2.default)(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; } // @ts-nocheck
|
|
@@ -49,7 +39,6 @@ function _superPropGet(t, o, e, r) { var p = (0, _get2.default)((0, _getPrototyp
|
|
|
49
39
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file
|
|
50
40
|
*/
|
|
51
41
|
var normalReconnectReasons = ['idle', 'done (forced)'];
|
|
52
|
-
var DEFAULT_MOBIUS_WEBSOCKET_SESSION = 'mobius-websocket-session';
|
|
53
42
|
var MOBIUS_SOCKET_NAMESPACE = 'MobiusSocket';
|
|
54
43
|
var TOKEN_REFRESH_INTERVAL_MS = 1 * 60 * 60 * 1000; // 1 hour
|
|
55
44
|
|
|
@@ -68,20 +57,16 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
68
57
|
_this.webex = webex;
|
|
69
58
|
_this.config = config;
|
|
70
59
|
_this.logger = webex.logger || console;
|
|
71
|
-
_this.defaultSessionId = DEFAULT_MOBIUS_WEBSOCKET_SESSION;
|
|
72
60
|
_this.connected = false;
|
|
73
61
|
_this.connecting = false;
|
|
74
62
|
_this.hasEverConnected = false;
|
|
75
63
|
_this.socket = undefined;
|
|
76
|
-
_this.
|
|
77
|
-
_this.
|
|
78
|
-
_this.
|
|
79
|
-
_this.
|
|
80
|
-
_this.
|
|
81
|
-
_this.
|
|
82
|
-
_this._tokenRefreshTimer = undefined;
|
|
83
|
-
_this._tokenRefreshInFlight = undefined;
|
|
84
|
-
_this._bindInternalEvents();
|
|
64
|
+
_this.backoffCall = undefined;
|
|
65
|
+
_this.shutdownSwitchoverBackoffCall = undefined;
|
|
66
|
+
_this.seenAsyncEventIds = new _map.default();
|
|
67
|
+
_this.connectPromise = undefined;
|
|
68
|
+
_this.tokenRefreshTimer = undefined;
|
|
69
|
+
_this.tokenRefreshInFlight = undefined;
|
|
85
70
|
return _this;
|
|
86
71
|
}
|
|
87
72
|
(0, _inherits2.default)(MobiusSocket, _EventEmitter);
|
|
@@ -94,143 +79,50 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
94
79
|
this.removeAllListeners(eventName);
|
|
95
80
|
return this;
|
|
96
81
|
}
|
|
97
|
-
}, {
|
|
98
|
-
key: "_bindInternalEvents",
|
|
99
|
-
value: function _bindInternalEvents() {
|
|
100
|
-
var _this2 = this;
|
|
101
|
-
/*
|
|
102
|
-
When one of these legacy feature gets updated, this event would be triggered
|
|
103
|
-
* group-message-notifications
|
|
104
|
-
* mention-notifications
|
|
105
|
-
* thread-notifications
|
|
106
|
-
*/
|
|
107
|
-
this.on('event:featureToggle_update', function (envelope) {
|
|
108
|
-
if (envelope && envelope.data) {
|
|
109
|
-
_this2.webex.internal.feature.updateFeature(envelope.data.featureToggle);
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
/*
|
|
113
|
-
* When Cluster Migrations, notify clients using ActiveClusterStatusEvent via mercury
|
|
114
|
-
* https://wwwin-github.cisco.com/pages/Webex/crr-docs/techdocs/rr-002.html#wip-notifying-clients-of-cluster-migrations
|
|
115
|
-
* */
|
|
116
|
-
this.on('event:ActiveClusterStatusEvent', function (envelope) {
|
|
117
|
-
var _this2$webex$internal;
|
|
118
|
-
if (typeof ((_this2$webex$internal = _this2.webex.internal.services) === null || _this2$webex$internal === void 0 ? void 0 : _this2$webex$internal.switchActiveClusterIds) === 'function' && envelope && envelope.data) {
|
|
119
|
-
var _envelope$data;
|
|
120
|
-
_this2.webex.internal.services.switchActiveClusterIds((_envelope$data = envelope.data) === null || _envelope$data === void 0 ? void 0 : _envelope$data.activeClusters);
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
/*
|
|
124
|
-
* Using cache-invalidation via mercury to instead the method of polling via the new /timestamp endpoint from u2c
|
|
125
|
-
* https://wwwin-github.cisco.com/pages/Webex/crr-docs/techdocs/rr-005.html#websocket-notifications
|
|
126
|
-
* */
|
|
127
|
-
this.on('event:u2c.cache-invalidation', function (envelope) {
|
|
128
|
-
var _this2$webex$internal2;
|
|
129
|
-
if (typeof ((_this2$webex$internal2 = _this2.webex.internal.services) === null || _this2$webex$internal2 === void 0 ? void 0 : _this2$webex$internal2.invalidateCache) === 'function' && envelope && envelope.data) {
|
|
130
|
-
var _envelope$data2;
|
|
131
|
-
_this2.webex.internal.services.invalidateCache((_envelope$data2 = envelope.data) === null || _envelope$data2 === void 0 ? void 0 : _envelope$data2.timestamp);
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
82
|
|
|
136
83
|
/**
|
|
137
84
|
* Attach event listeners to a socket.
|
|
138
85
|
* @param {Socket} socket - The socket to attach listeners to
|
|
139
|
-
* @param {sessionId} sessionId - The socket related session ID
|
|
140
86
|
* @returns {void}
|
|
141
87
|
*/
|
|
142
88
|
}, {
|
|
143
|
-
key: "
|
|
144
|
-
value: function
|
|
145
|
-
var
|
|
89
|
+
key: "attachSocketEventListeners",
|
|
90
|
+
value: function attachSocketEventListeners(socket) {
|
|
91
|
+
var _this2 = this;
|
|
146
92
|
socket.on('close', function (event) {
|
|
147
|
-
return
|
|
93
|
+
return _this2.onclose(event, socket);
|
|
148
94
|
});
|
|
149
95
|
socket.on('message', function () {
|
|
150
|
-
|
|
151
|
-
args[_key] = arguments[_key];
|
|
152
|
-
}
|
|
153
|
-
return _this3._onmessage.apply(_this3, [sessionId].concat(args));
|
|
154
|
-
});
|
|
155
|
-
socket.on('pong', function () {
|
|
156
|
-
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
157
|
-
args[_key2] = arguments[_key2];
|
|
158
|
-
}
|
|
159
|
-
return _this3._setTimeOffset.apply(_this3, [sessionId].concat(args));
|
|
160
|
-
});
|
|
161
|
-
socket.on('sequence-mismatch', function () {
|
|
162
|
-
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
163
|
-
args[_key3] = arguments[_key3];
|
|
164
|
-
}
|
|
165
|
-
return _this3._emit.apply(_this3, [sessionId, 'sequence-mismatch'].concat(args));
|
|
166
|
-
});
|
|
167
|
-
socket.on('ping-pong-latency', function () {
|
|
168
|
-
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
169
|
-
args[_key4] = arguments[_key4];
|
|
170
|
-
}
|
|
171
|
-
return _this3._emit.apply(_this3, [sessionId, 'ping-pong-latency'].concat(args));
|
|
96
|
+
return _this2.onmessage.apply(_this2, arguments);
|
|
172
97
|
});
|
|
173
98
|
}
|
|
174
99
|
|
|
175
|
-
/**
|
|
176
|
-
* Returns the per-session cache of seen async_event IDs, creating it on first access.
|
|
177
|
-
* @param {string} sessionId - The session identifier.
|
|
178
|
-
* @returns {Map<string, boolean>} Ordered cache of seen event IDs for the session.
|
|
179
|
-
*/
|
|
180
|
-
}, {
|
|
181
|
-
key: "_getSeenAsyncEventIds",
|
|
182
|
-
value: function _getSeenAsyncEventIds(sessionId) {
|
|
183
|
-
var seenAsyncEventIds = this._seenAsyncEventIdsBySession.get(sessionId);
|
|
184
|
-
if (!seenAsyncEventIds) {
|
|
185
|
-
seenAsyncEventIds = new _map.default();
|
|
186
|
-
this._seenAsyncEventIdsBySession.set(sessionId, seenAsyncEventIds);
|
|
187
|
-
}
|
|
188
|
-
return seenAsyncEventIds;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Clears the dedup cache for one session or for all sessions when omitted.
|
|
193
|
-
* @param {string} [sessionId] - Optional session identifier.
|
|
194
|
-
* @returns {void}
|
|
195
|
-
*/
|
|
196
|
-
}, {
|
|
197
|
-
key: "_clearSeenAsyncEventIds",
|
|
198
|
-
value: function _clearSeenAsyncEventIds(sessionId) {
|
|
199
|
-
if (sessionId) {
|
|
200
|
-
this._seenAsyncEventIdsBySession.delete(sessionId);
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
this._seenAsyncEventIdsBySession.clear();
|
|
204
|
-
}
|
|
205
|
-
|
|
206
100
|
/**
|
|
207
101
|
* Tracks a newly seen async_event ID and reports whether a duplicate should be suppressed.
|
|
208
|
-
* @param {string} sessionId - The session identifier.
|
|
209
102
|
* @param {object} envelope - Parsed websocket message envelope.
|
|
210
|
-
* @returns {boolean} True when the event has already been seen
|
|
103
|
+
* @returns {boolean} True when the event has already been seen.
|
|
211
104
|
*/
|
|
212
105
|
}, {
|
|
213
|
-
key: "
|
|
214
|
-
value: function
|
|
106
|
+
key: "trackAsyncEventAndShouldSuppressDuplicate",
|
|
107
|
+
value: function trackAsyncEventAndShouldSuppressDuplicate(envelope) {
|
|
215
108
|
if ((envelope === null || envelope === void 0 ? void 0 : envelope.type) !== 'async_event' || !envelope.eventId) {
|
|
216
109
|
return false;
|
|
217
110
|
}
|
|
218
|
-
|
|
219
|
-
if (seenAsyncEventIds.has(envelope.eventId)) {
|
|
220
|
-
var previousValue = seenAsyncEventIds.get(envelope.eventId);
|
|
221
|
-
|
|
111
|
+
if (this.seenAsyncEventIds.has(envelope.eventId)) {
|
|
222
112
|
// Refresh recency so frequently retransmitted eventIds stay protected longer.
|
|
223
|
-
|
|
224
|
-
seenAsyncEventIds.
|
|
225
|
-
this.
|
|
113
|
+
// This deletion and setting again makes the data recent since javascript map maintains order as well
|
|
114
|
+
var previousValue = this.seenAsyncEventIds.get(envelope.eventId);
|
|
115
|
+
this.seenAsyncEventIds.delete(envelope.eventId);
|
|
116
|
+
this.seenAsyncEventIds.set(envelope.eventId, previousValue);
|
|
117
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": duplicate async_event suppressed, eventId=").concat(envelope.eventId));
|
|
226
118
|
return true;
|
|
227
119
|
}
|
|
228
|
-
this.logger.
|
|
229
|
-
seenAsyncEventIds.set(envelope.eventId, true);
|
|
230
|
-
if (seenAsyncEventIds.size > this.config.dedupCacheMaxSize) {
|
|
231
|
-
var oldestEventId = seenAsyncEventIds.keys().next().value;
|
|
232
|
-
seenAsyncEventIds.delete(oldestEventId);
|
|
233
|
-
this.logger.
|
|
120
|
+
this.logger.log("".concat(MOBIUS_SOCKET_NAMESPACE, ": tracking async_event, eventId=").concat(envelope.eventId));
|
|
121
|
+
this.seenAsyncEventIds.set(envelope.eventId, true);
|
|
122
|
+
if (this.seenAsyncEventIds.size > this.config.dedupCacheMaxSize) {
|
|
123
|
+
var oldestEventId = this.seenAsyncEventIds.keys().next().value;
|
|
124
|
+
this.seenAsyncEventIds.delete(oldestEventId);
|
|
125
|
+
this.logger.log("".concat(MOBIUS_SOCKET_NAMESPACE, ": evicted oldest async_event from dedup cache, eventId=").concat(oldestEventId));
|
|
234
126
|
}
|
|
235
127
|
return false;
|
|
236
128
|
}
|
|
@@ -239,154 +131,88 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
239
131
|
* Handle imminent shutdown by establishing a new connection while keeping
|
|
240
132
|
* the current one alive (make-before-break).
|
|
241
133
|
* Idempotent: will no-op if already in progress.
|
|
242
|
-
* @param {string} sessionId - The session ID for which the shutdown is imminent
|
|
243
|
-
* @returns {void}
|
|
244
134
|
*/
|
|
245
135
|
}, {
|
|
246
|
-
key: "
|
|
247
|
-
value: function
|
|
248
|
-
var
|
|
249
|
-
var oldSocket = this.
|
|
136
|
+
key: "handleImminentShutdown",
|
|
137
|
+
value: function handleImminentShutdown() {
|
|
138
|
+
var _this3 = this;
|
|
139
|
+
var oldSocket = this.socket;
|
|
250
140
|
try {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if (this._shutdownSwitchoverBackoffCalls.get(sessionId)) {
|
|
254
|
-
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover already in progress for ").concat(sessionId));
|
|
141
|
+
if (this.shutdownSwitchoverBackoffCall) {
|
|
142
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover already in progress"));
|
|
255
143
|
return;
|
|
256
144
|
}
|
|
257
|
-
|
|
258
|
-
this.
|
|
259
|
-
this._connectWithBackoff(undefined, sessionId, {
|
|
145
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover start"));
|
|
146
|
+
this.connectWithBackoff(undefined, {
|
|
260
147
|
isShutdownSwitchover: true,
|
|
261
148
|
attemptOptions: {
|
|
262
149
|
isShutdownSwitchover: true,
|
|
263
150
|
onSuccess: function onSuccess(newSocket, webSocketUrl) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
//
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
151
|
+
_this3.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover connected, url: ").concat(webSocketUrl));
|
|
152
|
+
|
|
153
|
+
// Promote the new socket now that the switchover succeeded
|
|
154
|
+
newSocket.connecting = false;
|
|
155
|
+
newSocket.connected = true;
|
|
156
|
+
_this3.socket = newSocket;
|
|
157
|
+
_this3.connected = true;
|
|
158
|
+
_this3.emitEvent('event:mobius_shutdown_switchover_complete', {
|
|
271
159
|
url: webSocketUrl
|
|
272
160
|
});
|
|
273
161
|
if (oldSocket) {
|
|
274
|
-
|
|
162
|
+
_this3.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] old socket retained; server will close with 4001"));
|
|
275
163
|
}
|
|
276
164
|
}
|
|
277
165
|
}
|
|
278
166
|
}).then(function () {
|
|
279
|
-
|
|
167
|
+
_this3.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover completed successfully"));
|
|
280
168
|
}).catch(function (err) {
|
|
281
|
-
|
|
282
|
-
|
|
169
|
+
_this3.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover exhausted retries; will fall back to normal reconnection: "), err);
|
|
170
|
+
_this3.emitEvent('event:mobius_shutdown_switchover_failed', {
|
|
283
171
|
reason: err
|
|
284
172
|
});
|
|
285
|
-
// Old socket will eventually close with 4001, triggering normal reconnection
|
|
286
173
|
});
|
|
287
174
|
} catch (e) {
|
|
288
|
-
this.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] error during switchover
|
|
289
|
-
this.
|
|
290
|
-
this.
|
|
175
|
+
this.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] error during switchover"), e);
|
|
176
|
+
this.shutdownSwitchoverBackoffCall = undefined;
|
|
177
|
+
this.emitEvent('event:mobius_shutdown_switchover_failed', {
|
|
291
178
|
reason: e
|
|
292
179
|
});
|
|
293
180
|
}
|
|
294
181
|
}
|
|
295
182
|
|
|
296
183
|
/**
|
|
297
|
-
* Get the
|
|
298
|
-
* @returns {unknown} The last error.
|
|
299
|
-
*/
|
|
300
|
-
}, {
|
|
301
|
-
key: "getLastError",
|
|
302
|
-
value: function getLastError() {
|
|
303
|
-
return this.lastError;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Get all active socket connections
|
|
308
|
-
* @returns {Map} Map of sessionId to socket instances
|
|
309
|
-
*/
|
|
310
|
-
}, {
|
|
311
|
-
key: "getSockets",
|
|
312
|
-
value: function getSockets() {
|
|
313
|
-
return this.sockets;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* Get a specific socket by connection ID
|
|
318
|
-
* @param {string} sessionId - The connection identifier
|
|
319
|
-
* @returns {Socket|undefined} The socket instance or undefined if not found
|
|
320
|
-
*/
|
|
321
|
-
}, {
|
|
322
|
-
key: "getSocket",
|
|
323
|
-
value: function getSocket() {
|
|
324
|
-
var sessionId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.defaultSessionId;
|
|
325
|
-
return this.sockets.get(sessionId);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Get the websocket URL for a currently connected session.
|
|
330
|
-
* @param {string} [sessionId=this.defaultSessionId] - The session identifier.
|
|
184
|
+
* Get the websocket URL for the currently connected socket.
|
|
331
185
|
* @returns {string|undefined} The connected websocket URL, or undefined when not connected.
|
|
332
186
|
*/
|
|
333
187
|
}, {
|
|
334
188
|
key: "getConnectedWebSocketUrl",
|
|
335
189
|
value: function getConnectedWebSocketUrl() {
|
|
336
|
-
var
|
|
337
|
-
|
|
338
|
-
if (!(socket !== null && socket !== void 0 && socket.connected)) {
|
|
190
|
+
var _this$socket;
|
|
191
|
+
if (!((_this$socket = this.socket) !== null && _this$socket !== void 0 && _this$socket.connected)) {
|
|
339
192
|
return undefined;
|
|
340
193
|
}
|
|
341
|
-
return socket.url;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Sends a payload on the active connected socket
|
|
346
|
-
* @param {Object} payload - The data to send
|
|
347
|
-
* @param {string} [sessionId=this.defaultSessionId] - The session identifier
|
|
348
|
-
* @returns {Promise}
|
|
349
|
-
*/
|
|
350
|
-
}, {
|
|
351
|
-
key: "send",
|
|
352
|
-
value: function send(payload) {
|
|
353
|
-
var sessionId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.defaultSessionId;
|
|
354
|
-
var socket = this.getSocket(sessionId);
|
|
355
|
-
if (!socket || !socket.connected) {
|
|
356
|
-
return _promise.default.reject(new Error("Mobius socket is not connected for session ".concat(sessionId)));
|
|
357
|
-
}
|
|
358
|
-
return socket.send(payload);
|
|
194
|
+
return this.socket.url;
|
|
359
195
|
}
|
|
360
196
|
|
|
361
197
|
/**
|
|
362
198
|
* Sends a websocket request and resolves when the matching response arrives.
|
|
363
|
-
* @param {
|
|
364
|
-
* @param {
|
|
365
|
-
* @
|
|
366
|
-
* @returns {Promise<Object>}
|
|
199
|
+
* @param {MobiusSocketRequestPayload} payload - The websocket request payload.
|
|
200
|
+
* @param {MobiusSocketRequestOptions} [options={}] - Additional request options.
|
|
201
|
+
* @returns {Promise<SocketResponse>}
|
|
367
202
|
*/
|
|
368
203
|
}, {
|
|
369
204
|
key: "sendWssRequest",
|
|
370
205
|
value: function sendWssRequest(payload) {
|
|
371
|
-
var
|
|
372
|
-
var
|
|
373
|
-
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
206
|
+
var _this4 = this;
|
|
207
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
374
208
|
if (!payload || (0, _typeof2.default)(payload) !== 'object' || (0, _isArray.default)(payload)) {
|
|
375
209
|
return _promise.default.reject(new Error('`payload` is required'));
|
|
376
210
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
if (typeof sessionIdOrRequestOptions === 'string') {
|
|
380
|
-
sessionId = sessionIdOrRequestOptions;
|
|
381
|
-
} else if (sessionIdOrRequestOptions && (0, _typeof2.default)(sessionIdOrRequestOptions) === 'object') {
|
|
382
|
-
requestOptions = sessionIdOrRequestOptions;
|
|
211
|
+
if (!this.socket || !this.socket.connected) {
|
|
212
|
+
return _promise.default.reject(new Error('Mobius socket is not connected'));
|
|
383
213
|
}
|
|
384
|
-
var
|
|
385
|
-
|
|
386
|
-
return _promise.default.reject(new Error("Mobius socket is not connected for session ".concat(sessionId)));
|
|
387
|
-
}
|
|
388
|
-
return socket.sendRequest(payload, {
|
|
389
|
-
timeout: requestOptions.timeout,
|
|
214
|
+
var requestConfigOptions = {
|
|
215
|
+
timeout: options.timeout,
|
|
390
216
|
matchesResponse: function matchesResponse(response, request) {
|
|
391
217
|
return (response === null || response === void 0 ? void 0 : response.type) === 'response_event' && (response === null || response === void 0 ? void 0 : response.subtype) === request.type && (response === null || response === void 0 ? void 0 : response.trackingId) === request.trackingId;
|
|
392
218
|
},
|
|
@@ -397,21 +223,22 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
397
223
|
return response === null || response === void 0 ? void 0 : response.statusMessage;
|
|
398
224
|
},
|
|
399
225
|
createError: function createError(response, statusCode, statusMessage) {
|
|
400
|
-
return
|
|
226
|
+
return _this4.createWssResponseError(response, statusCode, statusMessage);
|
|
401
227
|
},
|
|
402
228
|
createTimeoutError: function createTimeoutError(request) {
|
|
403
|
-
return
|
|
229
|
+
return _this4.createWssResponseError({
|
|
404
230
|
type: 'response_event',
|
|
405
231
|
subtype: request.type,
|
|
406
232
|
trackingId: request.trackingId
|
|
407
233
|
}, 408, 'Mobius websocket response timed out');
|
|
408
234
|
}
|
|
409
|
-
}
|
|
235
|
+
};
|
|
236
|
+
return this.socket.sendRequest(payload, requestConfigOptions);
|
|
410
237
|
}
|
|
411
238
|
|
|
412
239
|
/**
|
|
413
|
-
* Check if the
|
|
414
|
-
* @returns {boolean} True if connected
|
|
240
|
+
* Check if the socket is connected.
|
|
241
|
+
* @returns {boolean} True if connected.
|
|
415
242
|
*/
|
|
416
243
|
}, {
|
|
417
244
|
key: "isConnected",
|
|
@@ -420,66 +247,22 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
420
247
|
}
|
|
421
248
|
|
|
422
249
|
/**
|
|
423
|
-
*
|
|
424
|
-
* @param {string} [sessionId] - Optional session identifier
|
|
425
|
-
* @returns {boolean|undefined} True if the socket is connected
|
|
426
|
-
*/
|
|
427
|
-
}, {
|
|
428
|
-
key: "hasConnectedSockets",
|
|
429
|
-
value: function hasConnectedSockets(sessionId) {
|
|
430
|
-
if (sessionId) {
|
|
431
|
-
var _this$sockets$get;
|
|
432
|
-
return Boolean((_this$sockets$get = this.sockets.get(sessionId)) === null || _this$sockets$get === void 0 ? void 0 : _this$sockets$get.connected);
|
|
433
|
-
}
|
|
434
|
-
var _iterator = _createForOfIteratorHelper(this.sockets.values()),
|
|
435
|
-
_step;
|
|
436
|
-
try {
|
|
437
|
-
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
438
|
-
var socket = _step.value;
|
|
439
|
-
if (socket !== null && socket !== void 0 && socket.connected) {
|
|
440
|
-
return true;
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
} catch (err) {
|
|
444
|
-
_iterator.e(err);
|
|
445
|
-
} finally {
|
|
446
|
-
_iterator.f();
|
|
447
|
-
}
|
|
448
|
-
return false;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
/**
|
|
452
|
-
* Check if any sockets are connecting
|
|
453
|
-
* @param {string} [sessionId=this.defaultSessionId] - The session identifier
|
|
454
|
-
* @returns {boolean|undefined} True if the socket is connecting
|
|
455
|
-
*/
|
|
456
|
-
}, {
|
|
457
|
-
key: "hasConnectingSockets",
|
|
458
|
-
value: function hasConnectingSockets() {
|
|
459
|
-
var sessionId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.defaultSessionId;
|
|
460
|
-
var socket = this.sockets.get(sessionId || this.defaultSessionId);
|
|
461
|
-
return Boolean(socket === null || socket === void 0 ? void 0 : socket.connecting);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/**
|
|
465
|
-
* Connect to Mobius for a specific session.
|
|
250
|
+
* Connect to Mobius.
|
|
466
251
|
* @param {string} [webSocketUrl] - Optional websocket URL override. Falls back to the device websocket URL.
|
|
467
|
-
* @
|
|
468
|
-
* @returns {Promise<void>} Resolves when connection flow completes for the session.
|
|
252
|
+
* @returns {Promise<void>} Resolves when connection flow completes.
|
|
469
253
|
*/
|
|
470
254
|
}, {
|
|
471
255
|
key: "connect",
|
|
472
256
|
value: function connect(webSocketUrl) {
|
|
473
|
-
var
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
if (this.
|
|
477
|
-
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connection
|
|
478
|
-
return this.
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connection ").concat(sessionId, " already connected, will not connect again"));
|
|
257
|
+
var _this$socket2,
|
|
258
|
+
_this$socket3,
|
|
259
|
+
_this5 = this;
|
|
260
|
+
if (this.connectPromise) {
|
|
261
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connection already in progress, returning existing promise"));
|
|
262
|
+
return this.connectPromise;
|
|
263
|
+
}
|
|
264
|
+
if ((_this$socket2 = this.socket) !== null && _this$socket2 !== void 0 && _this$socket2.connected || (_this$socket3 = this.socket) !== null && _this$socket3 !== void 0 && _this$socket3.connecting) {
|
|
265
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": already connected, will not connect again"));
|
|
483
266
|
return _promise.default.resolve();
|
|
484
267
|
}
|
|
485
268
|
|
|
@@ -490,120 +273,61 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
490
273
|
}
|
|
491
274
|
|
|
492
275
|
// Cache the caller-provided URL for reconnect
|
|
493
|
-
var resolvedUrl = webSocketUrl || this.socketUrl;
|
|
494
276
|
if (webSocketUrl) {
|
|
495
277
|
this.socketUrl = webSocketUrl;
|
|
496
278
|
}
|
|
497
279
|
this.connecting = true;
|
|
498
|
-
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": starting connection attempt
|
|
280
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": starting connection attempt").concat(Number(this.config.initialConnectionMaxRetries) === 0 && !this.hasEverConnected ? ' (initial retries disabled)' : ''));
|
|
499
281
|
var connectPromise = _promise.default.resolve(this.webex.internal.device.registered || this.webex.internal.device.register()).then(function () {
|
|
500
|
-
|
|
501
|
-
return
|
|
282
|
+
_this5.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connecting"));
|
|
283
|
+
return _this5.connectWithBackoff(_this5.socketUrl);
|
|
502
284
|
}).finally(function () {
|
|
503
|
-
|
|
285
|
+
_this5.connectPromise = undefined;
|
|
504
286
|
});
|
|
505
|
-
this.
|
|
287
|
+
this.connectPromise = connectPromise;
|
|
506
288
|
return connectPromise;
|
|
507
289
|
}
|
|
508
|
-
}, {
|
|
509
|
-
key: "logout",
|
|
510
|
-
value: function logout() {
|
|
511
|
-
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": logout() called"));
|
|
512
|
-
return this.disconnectAll(this.config.beforeLogoutOptionsCloseReason && !normalReconnectReasons.includes(this.config.beforeLogoutOptionsCloseReason) ? {
|
|
513
|
-
code: 3050,
|
|
514
|
-
reason: this.config.beforeLogoutOptionsCloseReason
|
|
515
|
-
} : undefined);
|
|
516
|
-
}
|
|
517
290
|
|
|
518
291
|
/**
|
|
519
|
-
* Disconnect
|
|
520
|
-
* @param {
|
|
521
|
-
* @
|
|
522
|
-
* @returns {Promise<void>} Resolves after disconnect cleanup and close handling are initiated/completed.
|
|
292
|
+
* Disconnect the Mobius socket.
|
|
293
|
+
* @param {MobiusSocketCloseOptions} [options] - Optional websocket close options (code, reason).
|
|
294
|
+
* @returns {Promise<void>} Resolves after disconnect cleanup and close handling complete.
|
|
523
295
|
*/
|
|
524
296
|
}, {
|
|
525
297
|
key: "disconnect",
|
|
526
298
|
value: function disconnect(options) {
|
|
527
|
-
var
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
this.
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
var sessionSocket = this.sockets.get(sessionId);
|
|
545
|
-
this._clearSeenAsyncEventIds(sessionId);
|
|
546
|
-
if (!sessionSocket) {
|
|
547
|
-
this.connected = this.hasConnectedSockets();
|
|
548
|
-
if (!this.hasConnectedSockets()) {
|
|
549
|
-
this._stopTokenRefreshTimer();
|
|
550
|
-
}
|
|
299
|
+
var _this6 = this;
|
|
300
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, "#disconnect: connecting state: ").concat(this.connecting, ",\n connected state: ").concat(this.connected, ", socket exists: ").concat(!!this.socket, ",\n options: ").concat((0, _stringify.default)(options)));
|
|
301
|
+
if (this.backoffCall) {
|
|
302
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": aborting connection"));
|
|
303
|
+
this.backoffCall.abort();
|
|
304
|
+
this.backoffCall = undefined;
|
|
305
|
+
}
|
|
306
|
+
if (this.shutdownSwitchoverBackoffCall) {
|
|
307
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": aborting shutdown switchover connection"));
|
|
308
|
+
this.shutdownSwitchoverBackoffCall.abort();
|
|
309
|
+
this.shutdownSwitchoverBackoffCall = undefined;
|
|
310
|
+
}
|
|
311
|
+
this.connectPromise = undefined;
|
|
312
|
+
this.seenAsyncEventIds.clear();
|
|
313
|
+
if (!this.socket) {
|
|
314
|
+
this.connected = false;
|
|
315
|
+
this.stopTokenRefreshTimer();
|
|
551
316
|
return _promise.default.resolve();
|
|
552
317
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
return _promise.default.resolve(
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
_this7._stopTokenRefreshTimer();
|
|
560
|
-
}
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
/**
|
|
565
|
-
* Disconnect all socket connections
|
|
566
|
-
* @param {object} options - Close options
|
|
567
|
-
* @returns {Promise} Promise that resolves when all connections are closed
|
|
568
|
-
*/
|
|
569
|
-
}, {
|
|
570
|
-
key: "disconnectAll",
|
|
571
|
-
value: function disconnectAll(options) {
|
|
572
|
-
var _this8 = this;
|
|
573
|
-
var disconnectPromises = [];
|
|
574
|
-
var _iterator2 = _createForOfIteratorHelper(this.sockets.keys()),
|
|
575
|
-
_step2;
|
|
576
|
-
try {
|
|
577
|
-
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
578
|
-
var sessionId = _step2.value;
|
|
579
|
-
disconnectPromises.push(this.disconnect(options, sessionId));
|
|
580
|
-
}
|
|
581
|
-
} catch (err) {
|
|
582
|
-
_iterator2.e(err);
|
|
583
|
-
} finally {
|
|
584
|
-
_iterator2.f();
|
|
585
|
-
}
|
|
586
|
-
return _promise.default.all(disconnectPromises).then(function () {
|
|
587
|
-
_this8.connected = false;
|
|
588
|
-
_this8.socket = undefined;
|
|
589
|
-
_this8.sockets.clear();
|
|
590
|
-
_this8.backoffCalls.clear();
|
|
591
|
-
_this8._shutdownSwitchoverBackoffCalls.clear();
|
|
592
|
-
_this8._clearSeenAsyncEventIds();
|
|
593
|
-
_this8._stopTokenRefreshTimer();
|
|
594
|
-
_this8._connectPromises.clear();
|
|
318
|
+
this.socket.removeAllListeners('message');
|
|
319
|
+
this.socket.connecting = false;
|
|
320
|
+
this.socket.connected = false;
|
|
321
|
+
return _promise.default.resolve(this.socket.close(options || undefined)).finally(function () {
|
|
322
|
+
_this6.connected = false;
|
|
323
|
+
_this6.stopTokenRefreshTimer();
|
|
595
324
|
});
|
|
596
325
|
}
|
|
597
|
-
}, {
|
|
598
|
-
key: "processRegistrationStatusEvent",
|
|
599
|
-
value: function processRegistrationStatusEvent(message) {
|
|
600
|
-
this.localClusterServiceUrls = message.localClusterServiceUrls;
|
|
601
|
-
}
|
|
602
326
|
|
|
603
327
|
// eslint-disable-next-line class-methods-use-this
|
|
604
328
|
}, {
|
|
605
|
-
key: "
|
|
606
|
-
value: function
|
|
329
|
+
key: "createWssResponseError",
|
|
330
|
+
value: function createWssResponseError(response, statusCode, statusMessage) {
|
|
607
331
|
var error = new Error(statusMessage || "Mobius websocket request failed with status ".concat(statusCode || 'unknown'));
|
|
608
332
|
error.name = 'MobiusSocketResponseError';
|
|
609
333
|
error.statusCode = statusCode;
|
|
@@ -612,43 +336,20 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
612
336
|
error.trackingId = response === null || response === void 0 ? void 0 : response.trackingId;
|
|
613
337
|
return error;
|
|
614
338
|
}
|
|
615
|
-
|
|
616
|
-
// eslint-disable-next-line class-methods-use-this
|
|
617
339
|
}, {
|
|
618
|
-
key: "
|
|
619
|
-
value: function
|
|
620
|
-
if (!event || !event.headers) {
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
var headerKeys = (0, _keys.default)(event.headers);
|
|
624
|
-
headerKeys.forEach(function (keyPath) {
|
|
625
|
-
(0, _set2.default)(event, keyPath, event.headers[keyPath]);
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
}, {
|
|
629
|
-
key: "_prepareUrl",
|
|
630
|
-
value: function _prepareUrl(webSocketUrl) {
|
|
340
|
+
key: "prepareUrl",
|
|
341
|
+
value: function prepareUrl(webSocketUrl) {
|
|
631
342
|
if (!webSocketUrl) {
|
|
343
|
+
// TODO: Circle back to this logic when mobius implements the shutdown switchover
|
|
632
344
|
webSocketUrl = this.webex.internal.device.webSocketUrl;
|
|
633
345
|
}
|
|
634
|
-
|
|
635
|
-
// TODO: Validate the host against the service catalog
|
|
636
|
-
// const hostFromUrl = url.parse(webSocketUrl, true)?.host;
|
|
637
|
-
// const isValidHost = this.webex.internal.services.isValidHost(hostFromUrl);
|
|
638
|
-
// if (!isValidHost) {
|
|
639
|
-
// this.logger.error(
|
|
640
|
-
// `${MOBIUS_SOCKET_NAMESPACE}: host ${hostFromUrl} is not a valid host from host catalog`
|
|
641
|
-
// );
|
|
642
|
-
// return Promise.resolve('');
|
|
643
|
-
// }
|
|
644
|
-
|
|
645
346
|
return _promise.default.resolve(webSocketUrl);
|
|
646
347
|
}
|
|
647
348
|
}, {
|
|
648
|
-
key: "
|
|
649
|
-
value: function
|
|
650
|
-
var
|
|
651
|
-
var options = arguments.length >
|
|
349
|
+
key: "attemptConnection",
|
|
350
|
+
value: function attemptConnection(socketUrl, callback) {
|
|
351
|
+
var _this7 = this;
|
|
352
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
652
353
|
var _options$isShutdownSw = options.isShutdownSwitchover,
|
|
653
354
|
isShutdownSwitchover = _options$isShutdownSw === void 0 ? false : _options$isShutdownSw,
|
|
654
355
|
_options$onSuccess = options.onSuccess,
|
|
@@ -656,16 +357,15 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
656
357
|
var socket = new _socket.default();
|
|
657
358
|
socket.connecting = true;
|
|
658
359
|
var newWSUrl;
|
|
659
|
-
this.
|
|
660
|
-
var backoffCall = isShutdownSwitchover ? this.
|
|
360
|
+
this.attachSocketEventListeners(socket);
|
|
361
|
+
var backoffCall = isShutdownSwitchover ? this.shutdownSwitchoverBackoffCall : this.backoffCall;
|
|
661
362
|
|
|
662
363
|
// Check appropriate backoff call based on connection type
|
|
663
364
|
if (!backoffCall) {
|
|
664
365
|
var mode = isShutdownSwitchover ? 'switchover backoff call' : 'backoffCall';
|
|
665
|
-
var msg = "".concat(MOBIUS_SOCKET_NAMESPACE, ": prevent socket open when ").concat(mode, " no longer defined
|
|
366
|
+
var msg = "".concat(MOBIUS_SOCKET_NAMESPACE, ": prevent socket open when ").concat(mode, " no longer defined");
|
|
666
367
|
var err = new Error(msg);
|
|
667
368
|
this.logger.info(msg);
|
|
668
|
-
|
|
669
369
|
// Call the callback with the error before rejecting
|
|
670
370
|
callback(err);
|
|
671
371
|
return _promise.default.reject(err);
|
|
@@ -674,11 +374,11 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
674
374
|
// For shutdown switchover, don't set socket yet (make-before-break)
|
|
675
375
|
// For normal connection, set socket before opening to allow disconnect() to close it
|
|
676
376
|
if (!isShutdownSwitchover) {
|
|
677
|
-
this.
|
|
377
|
+
this.socket = socket;
|
|
678
378
|
}
|
|
679
|
-
return this.
|
|
379
|
+
return this.prepareAndOpenSocket(socket, socketUrl, isShutdownSwitchover).then(function (webSocketUrl) {
|
|
680
380
|
newWSUrl = webSocketUrl;
|
|
681
|
-
|
|
381
|
+
_this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(isShutdownSwitchover ? '[shutdown] switchover' : '', " connected to mobius socket, success, url: ").concat(newWSUrl));
|
|
682
382
|
|
|
683
383
|
// Custom success handler for shutdown switchover
|
|
684
384
|
if (onSuccess) {
|
|
@@ -693,145 +393,130 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
693
393
|
}).catch(function (reason) {
|
|
694
394
|
// For shutdown, simpler error handling - just callback for retry
|
|
695
395
|
if (isShutdownSwitchover) {
|
|
696
|
-
|
|
396
|
+
_this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] switchover attempt failed"), reason);
|
|
697
397
|
return callback(reason);
|
|
698
398
|
}
|
|
699
399
|
|
|
700
|
-
// Normal connection error handling
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
var backoffCallNormal = _this9.backoffCalls.get(sessionId);
|
|
704
|
-
// Suppress connection errors that appear to be network related. This
|
|
705
|
-
// may end up suppressing metrics during outages, but we might not care
|
|
706
|
-
// (especially since many of our outages happen in a way that client
|
|
707
|
-
// metrics can't be trusted).
|
|
400
|
+
// Normal connection error handling
|
|
401
|
+
var backoffCallNormal = _this7.backoffCall;
|
|
402
|
+
// Suppress connection errors that appear to be network related (code 1006).
|
|
708
403
|
if (reason.code !== 1006 && backoffCallNormal && (backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.getNumRetries()) > 0) {
|
|
709
|
-
|
|
710
|
-
sessionId: sessionId,
|
|
404
|
+
_this7.emitEvent('connection_failed', reason, {
|
|
711
405
|
retries: backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.getNumRetries()
|
|
712
406
|
});
|
|
713
407
|
}
|
|
714
|
-
|
|
715
|
-
|
|
408
|
+
_this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connection attempt failed"), reason, (backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.getNumRetries()) === 0 ? reason.stack : '');
|
|
409
|
+
|
|
410
|
+
// UnknownResponse is produced by IE for any 4XXX; treat it like a bad
|
|
716
411
|
// web socket url and let WDM handle the token checking
|
|
717
412
|
if (reason instanceof _errors.UnknownResponse) {
|
|
718
|
-
|
|
719
|
-
return
|
|
413
|
+
_this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": received unknown response code, refreshing device registration"));
|
|
414
|
+
return _this7.webex.internal.device.refresh().then(function () {
|
|
720
415
|
return callback(reason);
|
|
721
416
|
});
|
|
722
417
|
}
|
|
723
418
|
// NotAuthorized implies expired token
|
|
724
419
|
if (reason instanceof _errors.NotAuthorized) {
|
|
725
|
-
|
|
726
|
-
return
|
|
420
|
+
_this7.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": received authorization error, reauthorizing"));
|
|
421
|
+
return _this7.webex.credentials.refresh({
|
|
727
422
|
force: true
|
|
728
423
|
}).then(function () {
|
|
729
424
|
return callback(reason);
|
|
730
425
|
});
|
|
731
426
|
}
|
|
732
|
-
// // NotFound implies expired web socket url
|
|
733
|
-
// else if (reason instanceof NotFound) {
|
|
734
|
-
// this.logger.info(`mercury: received not found error, refreshing device registration`);
|
|
735
|
-
// return this.webex.internal.device.refresh()
|
|
736
|
-
// .then(() => callback(reason));
|
|
737
|
-
// }
|
|
738
|
-
// BadRequest implies current credentials are for a Service Account
|
|
739
|
-
// Forbidden implies current user is not entitled for Webex
|
|
740
427
|
if (reason instanceof _errors.BadRequest || reason instanceof _errors.Forbidden) {
|
|
741
|
-
|
|
428
|
+
_this7.logger.warn("".concat(MOBIUS_SOCKET_NAMESPACE, ": received unrecoverable response from ").concat(MOBIUS_SOCKET_NAMESPACE));
|
|
742
429
|
backoffCallNormal === null || backoffCallNormal === void 0 ? void 0 : backoffCallNormal.abort();
|
|
743
430
|
return callback(reason);
|
|
744
431
|
}
|
|
745
432
|
return callback(reason);
|
|
746
433
|
}).catch(function (reason) {
|
|
747
|
-
|
|
434
|
+
_this7.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": failed to handle connection failure"), reason);
|
|
748
435
|
callback(reason);
|
|
749
436
|
});
|
|
750
437
|
}
|
|
751
438
|
}, {
|
|
752
|
-
key: "
|
|
753
|
-
value: function
|
|
754
|
-
var
|
|
755
|
-
var isShutdownSwitchover = arguments.length >
|
|
439
|
+
key: "prepareAndOpenSocket",
|
|
440
|
+
value: function prepareAndOpenSocket(socket, socketUrl) {
|
|
441
|
+
var _this8 = this;
|
|
442
|
+
var isShutdownSwitchover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
756
443
|
var logPrefix = isShutdownSwitchover ? '[shutdown] switchover' : 'connection';
|
|
757
|
-
return _promise.default.all([this.
|
|
444
|
+
return _promise.default.all([this.prepareUrl(socketUrl), this.webex.credentials.getUserToken()]).then(function (_ref) {
|
|
758
445
|
var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
|
|
759
446
|
webSocketUrl = _ref2[0],
|
|
760
447
|
token = _ref2[1];
|
|
761
448
|
var options = {
|
|
762
|
-
forceCloseDelay:
|
|
763
|
-
wssResponseTimeout:
|
|
764
|
-
skipAckEventId: _this0.config.skipAckEventId,
|
|
765
|
-
skipAckEventType: _this0.config.skipAckEventType,
|
|
449
|
+
forceCloseDelay: _this8.config.forceCloseDelay,
|
|
450
|
+
wssResponseTimeout: _this8.config.wssResponseTimeout,
|
|
766
451
|
token: normalizeMobiusAuthToken(token.toString()),
|
|
767
452
|
refreshToken: function refreshToken() {
|
|
768
|
-
return
|
|
453
|
+
return _this8.refreshToken();
|
|
769
454
|
},
|
|
770
|
-
trackingId: "".concat(
|
|
771
|
-
logger:
|
|
455
|
+
trackingId: "".concat(_this8.webex.sessionId, "_").concat((0, _now.default)()),
|
|
456
|
+
logger: _this8.logger
|
|
772
457
|
};
|
|
773
|
-
if (
|
|
458
|
+
if (_this8.webex.config.defaultMobiusSocketOptions) {
|
|
774
459
|
var customOptionsMsg = isShutdownSwitchover ? 'setting custom options for switchover' : 'setting custom options';
|
|
775
|
-
|
|
776
|
-
options = _objectSpread(_objectSpread({}, options),
|
|
460
|
+
_this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(customOptionsMsg));
|
|
461
|
+
options = _objectSpread(_objectSpread({}, options), _this8.webex.config.defaultMobiusSocketOptions);
|
|
777
462
|
}
|
|
778
463
|
|
|
779
|
-
//
|
|
780
|
-
// the socket
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
464
|
+
// Only promote the socket reference for normal connections.
|
|
465
|
+
// Shutdown switchover keeps the old socket active until the new one succeeds.
|
|
466
|
+
if (!isShutdownSwitchover) {
|
|
467
|
+
_this8.socket = socket;
|
|
468
|
+
}
|
|
469
|
+
_this8.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, " ").concat(logPrefix, " url: ").concat(webSocketUrl));
|
|
784
470
|
return socket.open(webSocketUrl, options).then(function () {
|
|
785
471
|
return webSocketUrl;
|
|
786
472
|
});
|
|
787
473
|
});
|
|
788
474
|
}
|
|
789
475
|
}, {
|
|
790
|
-
key: "
|
|
791
|
-
value: function
|
|
792
|
-
var
|
|
793
|
-
var context = arguments.length >
|
|
476
|
+
key: "connectWithBackoff",
|
|
477
|
+
value: function connectWithBackoff(webSocketUrl) {
|
|
478
|
+
var _this9 = this;
|
|
479
|
+
var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
794
480
|
var _context$isShutdownSw = context.isShutdownSwitchover,
|
|
795
481
|
isShutdownSwitchover = _context$isShutdownSw === void 0 ? false : _context$isShutdownSw,
|
|
796
482
|
_context$attemptOptio = context.attemptOptions,
|
|
797
483
|
attemptOptions = _context$attemptOptio === void 0 ? {} : _context$attemptOptio;
|
|
798
484
|
return new _promise.default(function (resolve, reject) {
|
|
799
|
-
// eslint gets confused about whether call is actually used
|
|
800
485
|
// eslint-disable-next-line prefer-const
|
|
801
486
|
var call;
|
|
802
|
-
var isInitialConnect = !isShutdownSwitchover && !
|
|
803
|
-
var initialRetryLimit =
|
|
487
|
+
var isInitialConnect = !isShutdownSwitchover && !_this9.hasEverConnected;
|
|
488
|
+
var initialRetryLimit = _this9.config.initialConnectionMaxRetries == null ? null : Number(_this9.config.initialConnectionMaxRetries);
|
|
804
489
|
var isInitialConnectWithoutRetries = isInitialConnect && initialRetryLimit === 0;
|
|
805
490
|
var onComplete = function onComplete(err) {
|
|
806
|
-
var sid = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : sessionId;
|
|
807
491
|
if (isShutdownSwitchover) {
|
|
808
|
-
|
|
492
|
+
_this9.shutdownSwitchoverBackoffCall = undefined;
|
|
809
493
|
} else {
|
|
810
|
-
|
|
494
|
+
_this9.backoffCall = undefined;
|
|
811
495
|
}
|
|
812
|
-
var sessionSocket = _this1.sockets.get(sid);
|
|
813
496
|
if (err) {
|
|
814
497
|
var msg = isShutdownSwitchover ? "[shutdown] switchover failed after ".concat(call.getNumRetries(), " retries") : "failed to connect after ".concat(call.getNumRetries(), " retries");
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
498
|
+
_this9.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(msg, "; ").concat(err));
|
|
499
|
+
// Only mutate socket flags for normal connections.
|
|
500
|
+
// During shutdown switchover, this.socket is the old live socket — don't touch it.
|
|
501
|
+
if (!isShutdownSwitchover && _this9.socket) {
|
|
502
|
+
_this9.socket.connecting = false;
|
|
503
|
+
_this9.socket.connected = false;
|
|
819
504
|
}
|
|
820
505
|
return reject(err);
|
|
821
506
|
}
|
|
822
507
|
|
|
823
|
-
//
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
508
|
+
// For normal connections, mark the socket as connected.
|
|
509
|
+
// Shutdown switchover promotion is handled by the onSuccess callback.
|
|
510
|
+
if (!isShutdownSwitchover && _this9.socket) {
|
|
511
|
+
_this9.socket.connecting = false;
|
|
512
|
+
_this9.socket.connected = true;
|
|
827
513
|
}
|
|
828
|
-
// Default success handling for normal connections
|
|
829
514
|
if (!isShutdownSwitchover) {
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
515
|
+
_this9.connecting = false;
|
|
516
|
+
_this9.connected = true;
|
|
517
|
+
_this9.hasEverConnected = true;
|
|
518
|
+
_this9.startTokenRefreshTimer();
|
|
519
|
+
_this9.emitEvent('online');
|
|
835
520
|
}
|
|
836
521
|
return resolve();
|
|
837
522
|
};
|
|
@@ -839,14 +524,14 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
839
524
|
call = _backoff.default.call(function (callback) {
|
|
840
525
|
var attemptNum = call.getNumRetries();
|
|
841
526
|
var attemptLogPrefix = isShutdownSwitchover ? '[shutdown] switchover' : 'connection';
|
|
842
|
-
|
|
843
|
-
|
|
527
|
+
_this9.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": executing ").concat(attemptLogPrefix, " attempt ").concat(attemptNum));
|
|
528
|
+
_this9.attemptConnection(webSocketUrl, callback, attemptOptions);
|
|
844
529
|
}, function (err) {
|
|
845
|
-
return onComplete(err
|
|
530
|
+
return onComplete(err);
|
|
846
531
|
});
|
|
847
532
|
call.setStrategy(new _backoff.default.ExponentialStrategy({
|
|
848
|
-
initialDelay:
|
|
849
|
-
maxDelay:
|
|
533
|
+
initialDelay: _this9.config.backoffTimeReset,
|
|
534
|
+
maxDelay: _this9.config.backoffTimeMax
|
|
850
535
|
}));
|
|
851
536
|
if (isInitialConnectWithoutRetries) {
|
|
852
537
|
call.retryIf(function () {
|
|
@@ -854,192 +539,141 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
854
539
|
});
|
|
855
540
|
} else if (isInitialConnect && initialRetryLimit > 0) {
|
|
856
541
|
call.failAfter(initialRetryLimit);
|
|
857
|
-
} else if (
|
|
858
|
-
call.failAfter(
|
|
542
|
+
} else if (_this9.config.maxRetries) {
|
|
543
|
+
call.failAfter(_this9.config.maxRetries);
|
|
859
544
|
}
|
|
860
545
|
|
|
861
|
-
// Store
|
|
862
|
-
// Store backoff call reference BEFORE starting (so it's available in _attemptConnection)
|
|
546
|
+
// Store backoff call reference BEFORE starting (so it's available in attemptConnection)
|
|
863
547
|
if (isShutdownSwitchover) {
|
|
864
|
-
|
|
548
|
+
_this9.shutdownSwitchoverBackoffCall = call;
|
|
865
549
|
} else {
|
|
866
|
-
|
|
550
|
+
_this9.backoffCall = call;
|
|
867
551
|
}
|
|
868
552
|
call.on('abort', function () {
|
|
869
553
|
var msg = isShutdownSwitchover ? 'Shutdown Switchover' : 'Connection';
|
|
870
|
-
|
|
871
|
-
reject(new Error("MobiusSocket ".concat(msg, " Aborted
|
|
554
|
+
_this9.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(msg, " aborted"));
|
|
555
|
+
reject(new Error("MobiusSocket ".concat(msg, " Aborted")));
|
|
872
556
|
});
|
|
873
557
|
call.on('callback', function (err) {
|
|
874
558
|
if (err) {
|
|
875
559
|
if (isInitialConnectWithoutRetries) {
|
|
876
|
-
|
|
877
|
-
// this branch only avoids logging the generic "attempting retry" message.
|
|
878
|
-
_this1.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": initial connect failed for ").concat(sessionId, "; retries already disabled"));
|
|
560
|
+
_this9.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": initial connect failed; retries already disabled"));
|
|
879
561
|
return;
|
|
880
562
|
}
|
|
881
563
|
var number = call.getNumRetries();
|
|
882
|
-
var delay = Math.min(call.strategy_.nextBackoffDelay_,
|
|
564
|
+
var delay = Math.min(call.strategy_.nextBackoffDelay_, _this9.config.backoffTimeMax);
|
|
883
565
|
var callbackLogPrefix = isShutdownSwitchover ? '[shutdown] switchover' : '';
|
|
884
|
-
|
|
566
|
+
_this9.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": ").concat(callbackLogPrefix, " failed to connect; attempting retry ").concat(number + 1, " in ").concat(delay, " ms"));
|
|
885
567
|
/* istanbul ignore if */
|
|
886
568
|
if (process.env.NODE_ENV === 'development') {
|
|
887
|
-
|
|
569
|
+
_this9.logger.debug("".concat(MOBIUS_SOCKET_NAMESPACE, ": "), err, err.stack);
|
|
888
570
|
}
|
|
889
571
|
return;
|
|
890
572
|
}
|
|
891
|
-
|
|
573
|
+
_this9.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": connected"));
|
|
892
574
|
});
|
|
893
575
|
call.start();
|
|
894
576
|
});
|
|
895
577
|
}
|
|
896
578
|
}, {
|
|
897
|
-
key: "
|
|
898
|
-
value: function
|
|
899
|
-
for (var
|
|
900
|
-
args[
|
|
579
|
+
key: "emitEvent",
|
|
580
|
+
value: function emitEvent(eventName) {
|
|
581
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
582
|
+
args[_key - 1] = arguments[_key];
|
|
901
583
|
}
|
|
902
584
|
try {
|
|
903
|
-
if (!
|
|
585
|
+
if (!eventName) {
|
|
904
586
|
return;
|
|
905
587
|
}
|
|
906
|
-
|
|
907
|
-
this.emit.apply(this, ["".concat(eventName).concat(suffix)].concat(args));
|
|
588
|
+
this.emit.apply(this, [eventName].concat(args));
|
|
908
589
|
} catch (error) {
|
|
909
590
|
// Safely handle errors without causing additional issues during cleanup
|
|
910
|
-
|
|
911
|
-
this.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": error occurred in event handler:"), error, ' with args: ', [sessionId, eventName].concat(args));
|
|
912
|
-
} catch (logError) {
|
|
913
|
-
// If even logging fails, just ignore to prevent cascading errors during cleanup
|
|
914
|
-
// eslint-disable-next-line no-console
|
|
915
|
-
console.error('MobiusSocket _emit error handling failed:', logError);
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
}, {
|
|
920
|
-
key: "_getEventHandlers",
|
|
921
|
-
value: function _getEventHandlers(eventType) {
|
|
922
|
-
if (!eventType) {
|
|
923
|
-
return [];
|
|
924
|
-
}
|
|
925
|
-
var _eventType$split = eventType.split('.'),
|
|
926
|
-
_eventType$split2 = (0, _slicedToArray2.default)(_eventType$split, 2),
|
|
927
|
-
namespace = _eventType$split2[0],
|
|
928
|
-
name = _eventType$split2[1];
|
|
929
|
-
var handlers = [];
|
|
930
|
-
if (!this.webex[namespace] && !this.webex.internal[namespace]) {
|
|
931
|
-
return handlers;
|
|
932
|
-
}
|
|
933
|
-
var handlerName = (0, _camelCase2.default)("process_".concat(name, "_event"));
|
|
934
|
-
if ((this.webex[namespace] || this.webex.internal[namespace])[handlerName]) {
|
|
935
|
-
handlers.push({
|
|
936
|
-
name: handlerName,
|
|
937
|
-
namespace: namespace
|
|
938
|
-
});
|
|
591
|
+
this.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": error occurred in event handler:"), error, ' with args: ', [eventName].concat(args));
|
|
939
592
|
}
|
|
940
|
-
return handlers;
|
|
941
593
|
}
|
|
942
594
|
}, {
|
|
943
|
-
key: "
|
|
944
|
-
value: function
|
|
945
|
-
var
|
|
946
|
-
if (this.
|
|
595
|
+
key: "startTokenRefreshTimer",
|
|
596
|
+
value: function startTokenRefreshTimer() {
|
|
597
|
+
var _this0 = this;
|
|
598
|
+
if (this.tokenRefreshTimer || !this.connected) {
|
|
947
599
|
return;
|
|
948
600
|
}
|
|
949
|
-
this.
|
|
950
|
-
|
|
951
|
-
|
|
601
|
+
this.tokenRefreshTimer = setInterval(function () {
|
|
602
|
+
_this0.refreshToken().catch(function (error) {
|
|
603
|
+
_this0.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": periodic token refresh failed"), error);
|
|
952
604
|
});
|
|
953
605
|
}, TOKEN_REFRESH_INTERVAL_MS);
|
|
954
606
|
}
|
|
955
607
|
}, {
|
|
956
|
-
key: "
|
|
957
|
-
value: function
|
|
958
|
-
if (!this.
|
|
608
|
+
key: "stopTokenRefreshTimer",
|
|
609
|
+
value: function stopTokenRefreshTimer() {
|
|
610
|
+
if (!this.tokenRefreshTimer) {
|
|
959
611
|
return;
|
|
960
612
|
}
|
|
961
|
-
clearInterval(this.
|
|
962
|
-
this.
|
|
613
|
+
clearInterval(this.tokenRefreshTimer);
|
|
614
|
+
this.tokenRefreshTimer = undefined;
|
|
963
615
|
}
|
|
964
616
|
}, {
|
|
965
|
-
key: "
|
|
966
|
-
value: function
|
|
967
|
-
var
|
|
968
|
-
if (this.
|
|
969
|
-
return this.
|
|
617
|
+
key: "refreshToken",
|
|
618
|
+
value: function refreshToken() {
|
|
619
|
+
var _this1 = this;
|
|
620
|
+
if (this.tokenRefreshInFlight) {
|
|
621
|
+
return this.tokenRefreshInFlight;
|
|
970
622
|
}
|
|
971
|
-
if (!this.
|
|
972
|
-
this.
|
|
623
|
+
if (!this.connected) {
|
|
624
|
+
this.stopTokenRefreshTimer();
|
|
973
625
|
return _promise.default.resolve();
|
|
974
626
|
}
|
|
975
627
|
var tokenPromise = this.webex.credentials.canRefresh ? this.webex.credentials.refresh({
|
|
976
628
|
force: true
|
|
977
629
|
}).then(function () {
|
|
978
|
-
return
|
|
630
|
+
return _this1.webex.credentials.getUserToken();
|
|
979
631
|
}) : this.webex.credentials.getUserToken();
|
|
980
|
-
this.
|
|
632
|
+
this.tokenRefreshInFlight = tokenPromise.then(function (token) {
|
|
633
|
+
var _this1$socket;
|
|
981
634
|
if (!token) {
|
|
982
635
|
throw new Error('Mobius token refresh did not return a token');
|
|
983
636
|
}
|
|
984
637
|
var refreshedToken = normalizeMobiusAuthToken(token.toString());
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
_step3;
|
|
988
|
-
try {
|
|
989
|
-
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
990
|
-
var socket = _step3.value;
|
|
991
|
-
if (socket !== null && socket !== void 0 && socket.connected) {
|
|
992
|
-
authPayloadPromises.push(socket.refresh(refreshedToken));
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
} catch (err) {
|
|
996
|
-
_iterator3.e(err);
|
|
997
|
-
} finally {
|
|
998
|
-
_iterator3.f();
|
|
638
|
+
if ((_this1$socket = _this1.socket) !== null && _this1$socket !== void 0 && _this1$socket.connected) {
|
|
639
|
+
return _this1.socket.refresh(refreshedToken);
|
|
999
640
|
}
|
|
1000
|
-
return
|
|
641
|
+
return undefined;
|
|
1001
642
|
}).catch(function (error) {
|
|
1002
|
-
|
|
643
|
+
_this1.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": failed to refresh/re-auth Mobius socket"), error);
|
|
1003
644
|
throw error;
|
|
1004
645
|
}).finally(function () {
|
|
1005
|
-
|
|
646
|
+
_this1.tokenRefreshInFlight = undefined;
|
|
1006
647
|
});
|
|
1007
|
-
return this.
|
|
648
|
+
return this.tokenRefreshInFlight;
|
|
1008
649
|
}
|
|
1009
650
|
}, {
|
|
1010
|
-
key: "
|
|
1011
|
-
value: function
|
|
651
|
+
key: "onclose",
|
|
652
|
+
value: function onclose(event, sourceSocket) {
|
|
1012
653
|
// I don't see any way to avoid the complexity or statement count in here.
|
|
1013
654
|
/* eslint complexity: [0] */
|
|
1014
655
|
|
|
1015
656
|
try {
|
|
1016
657
|
var reason = event.reason && event.reason.toLowerCase();
|
|
1017
|
-
var sessionSocket = this.sockets.get(sessionId);
|
|
1018
658
|
var socketUrl;
|
|
1019
|
-
|
|
1020
|
-
var isActiveSocket = sourceSocket === sessionSocket;
|
|
659
|
+
var isActiveSocket = sourceSocket === this.socket;
|
|
1021
660
|
if (sourceSocket) {
|
|
1022
661
|
socketUrl = sourceSocket.url;
|
|
1023
662
|
}
|
|
1024
|
-
|
|
663
|
+
|
|
664
|
+
// Only tear down state if the currently active socket closed
|
|
1025
665
|
if (isActiveSocket) {
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
this.socket = undefined;
|
|
1031
|
-
}
|
|
1032
|
-
this._emit(sessionId, 'offline', event);
|
|
1033
|
-
}
|
|
1034
|
-
// Update overall connected status
|
|
1035
|
-
this.connecting = this.hasConnectingSockets();
|
|
1036
|
-
this.connected = this.hasConnectedSockets();
|
|
1037
|
-
if (!this.hasConnectedSockets()) {
|
|
1038
|
-
this._stopTokenRefreshTimer();
|
|
666
|
+
if (this.socket) {
|
|
667
|
+
this.socket.removeAllListeners();
|
|
668
|
+
this.socket = undefined;
|
|
669
|
+
this.emitEvent('offline', event);
|
|
1039
670
|
}
|
|
671
|
+
this.connecting = false;
|
|
672
|
+
this.connected = false;
|
|
673
|
+
this.stopTokenRefreshTimer();
|
|
1040
674
|
} else {
|
|
1041
675
|
// Old socket closed; do not flip connection state
|
|
1042
|
-
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] non-active socket closed, code=").concat(event.code
|
|
676
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] non-active socket closed, code=").concat(event.code));
|
|
1043
677
|
// Clean up listeners from old socket now that it's closed
|
|
1044
678
|
if (sourceSocket) {
|
|
1045
679
|
sourceSocket.removeAllListeners();
|
|
@@ -1047,145 +681,111 @@ var MobiusSocket = /*#__PURE__*/function (_EventEmitter) {
|
|
|
1047
681
|
}
|
|
1048
682
|
switch (event.code) {
|
|
1049
683
|
case 1003:
|
|
1050
|
-
|
|
1051
|
-
this.
|
|
1052
|
-
if (isActiveSocket) this._emit(sessionId, 'offline.permanent', event);
|
|
684
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": service rejected last message; will not reconnect: ").concat(event.reason));
|
|
685
|
+
if (isActiveSocket) this.emitEvent('offline.permanent', event);
|
|
1053
686
|
break;
|
|
1054
687
|
case 4000:
|
|
1055
|
-
|
|
1056
|
-
this.
|
|
1057
|
-
if (isActiveSocket) this._emit(sessionId, 'offline.replaced', event);
|
|
1058
|
-
// If not active, nothing to do
|
|
688
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket replaced; will not reconnect"));
|
|
689
|
+
if (isActiveSocket) this.emitEvent('offline.replaced', event);
|
|
1059
690
|
break;
|
|
1060
691
|
case 4001:
|
|
1061
692
|
// replaced during shutdown
|
|
1062
693
|
if (isActiveSocket) {
|
|
1063
694
|
// Server closed active socket with 4001, meaning it expected this connection
|
|
1064
|
-
// to be replaced, but the switchover in
|
|
1065
|
-
|
|
1066
|
-
this.
|
|
1067
|
-
this._emit(sessionId, 'offline.permanent', event);
|
|
695
|
+
// to be replaced, but the switchover in handleImminentShutdown failed.
|
|
696
|
+
this.logger.warn("".concat(MOBIUS_SOCKET_NAMESPACE, ": active socket closed with 4001; shutdown switchover failed"));
|
|
697
|
+
this.emitEvent('offline.permanent', event);
|
|
1068
698
|
} else {
|
|
1069
699
|
// Expected: old socket closed after successful switchover
|
|
1070
|
-
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": old socket closed with 4001 (replaced during shutdown); no reconnect needed
|
|
1071
|
-
this.
|
|
700
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": old socket closed with 4001 (replaced during shutdown); no reconnect needed"));
|
|
701
|
+
this.emitEvent('offline.replaced', event);
|
|
1072
702
|
}
|
|
1073
703
|
break;
|
|
1074
704
|
case 1001:
|
|
1075
705
|
case 1005:
|
|
1076
706
|
case 1006:
|
|
1077
707
|
case 1011:
|
|
1078
|
-
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket
|
|
708
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket disconnected; reconnecting"));
|
|
1079
709
|
if (isActiveSocket) {
|
|
1080
|
-
this.
|
|
1081
|
-
this.
|
|
1082
|
-
this._reconnect(socketUrl, sessionId);
|
|
710
|
+
this.emitEvent('offline.transient', event);
|
|
711
|
+
this.reconnect(socketUrl);
|
|
1083
712
|
}
|
|
1084
|
-
// metric: disconnect
|
|
1085
|
-
// if (code == 1011 && reason !== ping error) metric: unexpected disconnect
|
|
1086
713
|
break;
|
|
1087
714
|
case 1000:
|
|
1088
715
|
case 3050:
|
|
1089
|
-
// 3050 indicates logout form of closure, default to old behavior, use config reason defined by consumer to proceed with the permanent block
|
|
1090
716
|
if (normalReconnectReasons.includes(reason)) {
|
|
1091
|
-
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket
|
|
717
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket disconnected; reconnecting"));
|
|
1092
718
|
if (isActiveSocket) {
|
|
1093
|
-
this.
|
|
1094
|
-
this.
|
|
1095
|
-
this._reconnect(socketUrl, sessionId);
|
|
719
|
+
this.emitEvent('offline.transient', event);
|
|
720
|
+
this.reconnect(socketUrl);
|
|
1096
721
|
}
|
|
1097
|
-
// metric: disconnect
|
|
1098
|
-
// if (reason === done forced) metric: force closure
|
|
1099
722
|
} else {
|
|
1100
|
-
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket
|
|
1101
|
-
if (isActiveSocket) this.
|
|
723
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket disconnected; will not reconnect: ").concat(event.reason));
|
|
724
|
+
if (isActiveSocket) this.emitEvent('offline.permanent', event);
|
|
1102
725
|
}
|
|
1103
726
|
break;
|
|
1104
727
|
default:
|
|
1105
|
-
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket
|
|
1106
|
-
|
|
1107
|
-
if (isActiveSocket) this._emit(sessionId, 'offline.permanent', event);
|
|
728
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": socket disconnected unexpectedly; will not reconnect"));
|
|
729
|
+
if (isActiveSocket) this.emitEvent('offline.permanent', event);
|
|
1108
730
|
}
|
|
1109
731
|
} catch (error) {
|
|
1110
|
-
this.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": error occurred in close handler
|
|
732
|
+
this.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": error occurred in close handler"), error);
|
|
1111
733
|
}
|
|
1112
734
|
}
|
|
1113
735
|
}, {
|
|
1114
|
-
key: "
|
|
1115
|
-
value: function
|
|
1116
|
-
var _this12 = this;
|
|
1117
|
-
this._setTimeOffset(sessionId, event);
|
|
736
|
+
key: "onmessage",
|
|
737
|
+
value: function onmessage(event) {
|
|
1118
738
|
var envelope = event.data;
|
|
1119
|
-
if (process.env.
|
|
1120
|
-
this.logger.debug("".concat(MOBIUS_SOCKET_NAMESPACE, ": message envelope
|
|
739
|
+
if (process.env.ENABLE_MOBIUS_LOGGING) {
|
|
740
|
+
this.logger.debug("".concat(MOBIUS_SOCKET_NAMESPACE, ": message envelope: "), envelope);
|
|
1121
741
|
}
|
|
1122
|
-
envelope.sessionId = sessionId;
|
|
1123
742
|
|
|
1124
743
|
// Handle shutdown message shape: { type: 'shutdown' }
|
|
1125
744
|
if (envelope && envelope.type === 'shutdown') {
|
|
1126
|
-
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] imminent shutdown message received
|
|
1127
|
-
this.
|
|
1128
|
-
|
|
745
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": [shutdown] imminent shutdown message received"));
|
|
746
|
+
this.emitEvent('event:mobius_shutdown_imminent', envelope); // This is not yet not implemented, keeping for future support
|
|
747
|
+
|
|
748
|
+
this.handleImminentShutdown();
|
|
1129
749
|
return _promise.default.resolve();
|
|
1130
750
|
}
|
|
1131
|
-
if (this.
|
|
751
|
+
if (this.trackAsyncEventAndShouldSuppressDuplicate(envelope)) {
|
|
1132
752
|
return _promise.default.resolve();
|
|
1133
753
|
}
|
|
1134
754
|
|
|
1135
|
-
//
|
|
755
|
+
// Emit event:<type> for typed messages (e.g., register.response)
|
|
1136
756
|
if (envelope.type) {
|
|
1137
|
-
this.
|
|
757
|
+
this.emitEvent("event:".concat(envelope.type), envelope);
|
|
1138
758
|
}
|
|
1139
|
-
|
|
759
|
+
|
|
1140
760
|
// Use data/payload if present, otherwise treat the envelope itself as the data (flat format)
|
|
1141
761
|
var data = envelope.data || envelope;
|
|
1142
|
-
this._applyOverrides(data);
|
|
1143
762
|
|
|
1144
|
-
// Support both
|
|
763
|
+
// Support both Mobius-enveloped (data.eventType) and flat (eventType) formats
|
|
1145
764
|
var eventType = (data === null || data === void 0 ? void 0 : data.eventType) || envelope.eventType;
|
|
1146
765
|
if (!eventType) {
|
|
1147
|
-
this.
|
|
766
|
+
this.emitEvent('event', envelope);
|
|
1148
767
|
return _promise.default.resolve();
|
|
1149
768
|
}
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
});
|
|
1160
|
-
}, _promise.default.resolve()).then(function () {
|
|
1161
|
-
_this12._emit(sessionId, 'event', envelope);
|
|
1162
|
-
var _eventType$split3 = eventType.split('.'),
|
|
1163
|
-
_eventType$split4 = (0, _slicedToArray2.default)(_eventType$split3, 1),
|
|
1164
|
-
namespace = _eventType$split4[0];
|
|
1165
|
-
if (namespace === eventType) {
|
|
1166
|
-
_this12._emit(sessionId, "event:".concat(namespace), envelope);
|
|
1167
|
-
} else {
|
|
1168
|
-
_this12._emit(sessionId, "event:".concat(namespace), envelope);
|
|
1169
|
-
_this12._emit(sessionId, "event:".concat(eventType), envelope);
|
|
769
|
+
try {
|
|
770
|
+
// TODO: Remove if event:namespace is not required
|
|
771
|
+
this.emitEvent('event', envelope);
|
|
772
|
+
var _eventType$split = eventType.split('.'),
|
|
773
|
+
_eventType$split2 = (0, _slicedToArray2.default)(_eventType$split, 1),
|
|
774
|
+
namespace = _eventType$split2[0];
|
|
775
|
+
this.emitEvent("event:".concat(namespace), envelope);
|
|
776
|
+
if (namespace !== eventType) {
|
|
777
|
+
this.emitEvent("event:".concat(eventType), envelope);
|
|
1170
778
|
}
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
});
|
|
1174
|
-
}
|
|
1175
|
-
}, {
|
|
1176
|
-
key: "_setTimeOffset",
|
|
1177
|
-
value: function _setTimeOffset(sessionId, event) {
|
|
1178
|
-
var wsWriteTimestamp = event.data.wsWriteTimestamp;
|
|
1179
|
-
if (typeof wsWriteTimestamp === 'number' && wsWriteTimestamp > 0) {
|
|
1180
|
-
this.mercuryTimeOffset = (0, _now.default)() - wsWriteTimestamp;
|
|
779
|
+
} catch (reason) {
|
|
780
|
+
this.logger.error("".concat(MOBIUS_SOCKET_NAMESPACE, ": error occurred processing socket message"), reason);
|
|
1181
781
|
}
|
|
782
|
+
return _promise.default.resolve();
|
|
1182
783
|
}
|
|
1183
784
|
}, {
|
|
1184
|
-
key: "
|
|
1185
|
-
value: function
|
|
1186
|
-
|
|
1187
|
-
this.
|
|
1188
|
-
return this.connect(webSocketUrl || this.socketUrl, sessionId);
|
|
785
|
+
key: "reconnect",
|
|
786
|
+
value: function reconnect(webSocketUrl) {
|
|
787
|
+
this.logger.info("".concat(MOBIUS_SOCKET_NAMESPACE, ": reconnecting"));
|
|
788
|
+
return this.connect(webSocketUrl || this.socketUrl);
|
|
1189
789
|
}
|
|
1190
790
|
}]);
|
|
1191
791
|
}(_events.EventEmitter);
|