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