@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.
Files changed (41) hide show
  1. package/dist/CallingClient/utils/request.js +6 -3
  2. package/dist/CallingClient/utils/request.js.map +1 -1
  3. package/dist/CallingClient/utils/request.test.js +2 -2
  4. package/dist/CallingClient/utils/request.test.js.map +1 -1
  5. package/dist/CallingClient/utils/types.js.map +1 -1
  6. package/dist/mobius-socket/config.js +7 -44
  7. package/dist/mobius-socket/config.js.map +1 -1
  8. package/dist/mobius-socket/errors.js +25 -21
  9. package/dist/mobius-socket/errors.js.map +1 -1
  10. package/dist/mobius-socket/index.js +0 -44
  11. package/dist/mobius-socket/index.js.map +1 -1
  12. package/dist/mobius-socket/mobius-socket-events.test.js +20 -48
  13. package/dist/mobius-socket/mobius-socket-events.test.js.map +1 -1
  14. package/dist/mobius-socket/mobius-socket.js +301 -701
  15. package/dist/mobius-socket/mobius-socket.js.map +1 -1
  16. package/dist/mobius-socket/mobius-socket.test.js +435 -718
  17. package/dist/mobius-socket/mobius-socket.test.js.map +1 -1
  18. package/dist/mobius-socket/socket/socket-base.js +70 -78
  19. package/dist/mobius-socket/socket/socket-base.js.map +1 -1
  20. package/dist/mobius-socket/socket.test.js +36 -61
  21. package/dist/mobius-socket/socket.test.js.map +1 -1
  22. package/dist/module/CallingClient/utils/request.js +3 -2
  23. package/dist/module/mobius-socket/config.js +7 -10
  24. package/dist/module/mobius-socket/errors.js +17 -0
  25. package/dist/module/mobius-socket/index.js +0 -3
  26. package/dist/module/mobius-socket/mobius-socket.js +211 -398
  27. package/dist/module/mobius-socket/socket/socket-base.js +64 -69
  28. package/dist/types/CallingClient/utils/request.d.ts.map +1 -1
  29. package/dist/types/CallingClient/utils/types.d.ts +1 -1
  30. package/dist/types/CallingClient/utils/types.d.ts.map +1 -1
  31. package/dist/types/mobius-socket/config.d.ts +7 -8
  32. package/dist/types/mobius-socket/config.d.ts.map +1 -1
  33. package/dist/types/mobius-socket/errors.d.ts +7 -0
  34. package/dist/types/mobius-socket/errors.d.ts.map +1 -1
  35. package/dist/types/mobius-socket/index.d.ts +1 -5
  36. package/dist/types/mobius-socket/index.d.ts.map +1 -1
  37. package/dist/types/mobius-socket/mobius-socket.d.ts +20 -35
  38. package/dist/types/mobius-socket/mobius-socket.d.ts.map +1 -1
  39. package/dist/types/mobius-socket/socket/socket-base.d.ts +10 -10
  40. package/dist/types/mobius-socket/socket/socket-base.d.ts.map +1 -1
  41. package/package.json +1 -1
@@ -2,12 +2,10 @@
2
2
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file
3
3
  */
4
4
  import { EventEmitter } from 'events';
5
- import { camelCase, set } from 'lodash';
6
5
  import backoff from 'backoff';
7
6
  import Socket from './socket';
8
- import { BadRequest, Forbidden, NotAuthorized, UnknownResponse, } from './errors';
7
+ import { BadRequest, Forbidden, NotAuthorized, UnknownResponse } from './errors';
9
8
  const normalReconnectReasons = ['idle', 'done (forced)'];
10
- const DEFAULT_MOBIUS_WEBSOCKET_SESSION = 'mobius-websocket-session';
11
9
  const MOBIUS_SOCKET_NAMESPACE = 'MobiusSocket';
12
10
  const TOKEN_REFRESH_INTERVAL_MS = 1 * 60 * 60 * 1000;
13
11
  function normalizeMobiusAuthToken(token) {
@@ -22,20 +20,16 @@ class MobiusSocket extends EventEmitter {
22
20
  this.webex = webex;
23
21
  this.config = config;
24
22
  this.logger = webex.logger || console;
25
- this.defaultSessionId = DEFAULT_MOBIUS_WEBSOCKET_SESSION;
26
23
  this.connected = false;
27
24
  this.connecting = false;
28
25
  this.hasEverConnected = false;
29
26
  this.socket = undefined;
30
- this.sockets = new Map();
31
- this.backoffCalls = new Map();
32
- this._shutdownSwitchoverBackoffCalls = new Map();
33
- this._seenAsyncEventIdsBySession = new Map();
34
- this._connectPromises = new Map();
35
- this.mercuryTimeOffset = undefined;
36
- this._tokenRefreshTimer = undefined;
37
- this._tokenRefreshInFlight = undefined;
38
- this._bindInternalEvents();
27
+ this.backoffCall = undefined;
28
+ this.shutdownSwitchoverBackoffCall = undefined;
29
+ this.seenAsyncEventIds = new Map();
30
+ this.connectPromise = undefined;
31
+ this.tokenRefreshTimer = undefined;
32
+ this.tokenRefreshInFlight = undefined;
39
33
  }
40
34
  off(eventName, listener) {
41
35
  if (listener) {
@@ -44,88 +38,49 @@ class MobiusSocket extends EventEmitter {
44
38
  this.removeAllListeners(eventName);
45
39
  return this;
46
40
  }
47
- _bindInternalEvents() {
48
- this.on('event:featureToggle_update', (envelope) => {
49
- if (envelope && envelope.data) {
50
- this.webex.internal.feature.updateFeature(envelope.data.featureToggle);
51
- }
52
- });
53
- this.on('event:ActiveClusterStatusEvent', (envelope) => {
54
- if (typeof this.webex.internal.services?.switchActiveClusterIds === 'function' &&
55
- envelope &&
56
- envelope.data) {
57
- this.webex.internal.services.switchActiveClusterIds(envelope.data?.activeClusters);
58
- }
59
- });
60
- this.on('event:u2c.cache-invalidation', (envelope) => {
61
- if (typeof this.webex.internal.services?.invalidateCache === 'function' &&
62
- envelope &&
63
- envelope.data) {
64
- this.webex.internal.services.invalidateCache(envelope.data?.timestamp);
65
- }
66
- });
41
+ attachSocketEventListeners(socket) {
42
+ socket.on('close', (event) => this.onclose(event, socket));
43
+ socket.on('message', (...args) => this.onmessage(...args));
67
44
  }
68
- _attachSocketEventListeners(socket, sessionId) {
69
- socket.on('close', (event) => this._onclose(sessionId, event, socket));
70
- socket.on('message', (...args) => this._onmessage(sessionId, ...args));
71
- socket.on('pong', (...args) => this._setTimeOffset(sessionId, ...args));
72
- socket.on('sequence-mismatch', (...args) => this._emit(sessionId, 'sequence-mismatch', ...args));
73
- socket.on('ping-pong-latency', (...args) => this._emit(sessionId, 'ping-pong-latency', ...args));
74
- }
75
- _getSeenAsyncEventIds(sessionId) {
76
- let seenAsyncEventIds = this._seenAsyncEventIdsBySession.get(sessionId);
77
- if (!seenAsyncEventIds) {
78
- seenAsyncEventIds = new Map();
79
- this._seenAsyncEventIdsBySession.set(sessionId, seenAsyncEventIds);
80
- }
81
- return seenAsyncEventIds;
82
- }
83
- _clearSeenAsyncEventIds(sessionId) {
84
- if (sessionId) {
85
- this._seenAsyncEventIdsBySession.delete(sessionId);
86
- return;
87
- }
88
- this._seenAsyncEventIdsBySession.clear();
89
- }
90
- _trackAsyncEventAndShouldSuppressDuplicate(sessionId, envelope) {
45
+ trackAsyncEventAndShouldSuppressDuplicate(envelope) {
91
46
  if (envelope?.type !== 'async_event' || !envelope.eventId) {
92
47
  return false;
93
48
  }
94
- const seenAsyncEventIds = this._getSeenAsyncEventIds(sessionId);
95
- if (seenAsyncEventIds.has(envelope.eventId)) {
96
- const previousValue = seenAsyncEventIds.get(envelope.eventId);
97
- seenAsyncEventIds.delete(envelope.eventId);
98
- seenAsyncEventIds.set(envelope.eventId, previousValue);
99
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: duplicate async_event suppressed for ${sessionId}, eventId=${envelope.eventId}`);
49
+ if (this.seenAsyncEventIds.has(envelope.eventId)) {
50
+ const previousValue = this.seenAsyncEventIds.get(envelope.eventId);
51
+ this.seenAsyncEventIds.delete(envelope.eventId);
52
+ this.seenAsyncEventIds.set(envelope.eventId, previousValue);
53
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: duplicate async_event suppressed, eventId=${envelope.eventId}`);
100
54
  return true;
101
55
  }
102
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: tracking async_event for ${sessionId}, eventId=${envelope.eventId}`);
103
- seenAsyncEventIds.set(envelope.eventId, true);
104
- if (seenAsyncEventIds.size > this.config.dedupCacheMaxSize) {
105
- const oldestEventId = seenAsyncEventIds.keys().next().value;
106
- seenAsyncEventIds.delete(oldestEventId);
107
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: evicted oldest async_event from dedup cache for ${sessionId}, eventId=${oldestEventId}`);
56
+ this.logger.log(`${MOBIUS_SOCKET_NAMESPACE}: tracking async_event, eventId=${envelope.eventId}`);
57
+ this.seenAsyncEventIds.set(envelope.eventId, true);
58
+ if (this.seenAsyncEventIds.size > this.config.dedupCacheMaxSize) {
59
+ const oldestEventId = this.seenAsyncEventIds.keys().next().value;
60
+ this.seenAsyncEventIds.delete(oldestEventId);
61
+ this.logger.log(`${MOBIUS_SOCKET_NAMESPACE}: evicted oldest async_event from dedup cache, eventId=${oldestEventId}`);
108
62
  }
109
63
  return false;
110
64
  }
111
- _handleImminentShutdown(sessionId) {
112
- const oldSocket = this.sockets.get(sessionId);
65
+ handleImminentShutdown() {
66
+ const oldSocket = this.socket;
113
67
  try {
114
- if (this._shutdownSwitchoverBackoffCalls.get(sessionId)) {
115
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] switchover already in progress for ${sessionId}`);
68
+ if (this.shutdownSwitchoverBackoffCall) {
69
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] switchover already in progress`);
116
70
  return;
117
71
  }
118
- const switchoverId = `${Date.now()}`;
119
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] switchover start, id=${switchoverId} for ${sessionId}`);
120
- this._connectWithBackoff(undefined, sessionId, {
72
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] switchover start`);
73
+ this.connectWithBackoff(undefined, {
121
74
  isShutdownSwitchover: true,
122
75
  attemptOptions: {
123
76
  isShutdownSwitchover: true,
124
77
  onSuccess: (newSocket, webSocketUrl) => {
125
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] switchover connected, url: ${webSocketUrl} for ${sessionId}`);
126
- this.socket = this.sockets.get(this.defaultSessionId);
127
- this.connected = this.hasConnectedSockets();
128
- this._emit(sessionId, 'event:mercury_shutdown_switchover_complete', {
78
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] switchover connected, url: ${webSocketUrl}`);
79
+ newSocket.connecting = false;
80
+ newSocket.connected = true;
81
+ this.socket = newSocket;
82
+ this.connected = true;
83
+ this.emitEvent('event:mobius_shutdown_switchover_complete', {
129
84
  url: webSocketUrl,
130
85
  });
131
86
  if (oldSocket) {
@@ -135,185 +90,111 @@ class MobiusSocket extends EventEmitter {
135
90
  },
136
91
  })
137
92
  .then(() => {
138
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] switchover completed successfully for ${sessionId}`);
93
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] switchover completed successfully`);
139
94
  })
140
95
  .catch((err) => {
141
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] switchover exhausted retries; will fall back to normal reconnection for ${sessionId}: `, err);
142
- this._emit(sessionId, 'event:mercury_shutdown_switchover_failed', { reason: err });
96
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] switchover exhausted retries; will fall back to normal reconnection: `, err);
97
+ this.emitEvent('event:mobius_shutdown_switchover_failed', { reason: err });
143
98
  });
144
99
  }
145
100
  catch (e) {
146
- this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] error during switchover for ${sessionId}`, e);
147
- this._shutdownSwitchoverBackoffCalls.delete(sessionId);
148
- this._emit(sessionId, 'event:mercury_shutdown_switchover_failed', { reason: e });
101
+ this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] error during switchover`, e);
102
+ this.shutdownSwitchoverBackoffCall = undefined;
103
+ this.emitEvent('event:mobius_shutdown_switchover_failed', { reason: e });
149
104
  }
150
105
  }
151
- getLastError() {
152
- return this.lastError;
153
- }
154
- getSockets() {
155
- return this.sockets;
156
- }
157
- getSocket(sessionId = this.defaultSessionId) {
158
- return this.sockets.get(sessionId);
159
- }
160
- getConnectedWebSocketUrl(sessionId = this.defaultSessionId) {
161
- const socket = this.getSocket(sessionId);
162
- if (!socket?.connected) {
106
+ getConnectedWebSocketUrl() {
107
+ if (!this.socket?.connected) {
163
108
  return undefined;
164
109
  }
165
- return socket.url;
110
+ return this.socket.url;
166
111
  }
167
- send(payload, sessionId = this.defaultSessionId) {
168
- const socket = this.getSocket(sessionId);
169
- if (!socket || !socket.connected) {
170
- return Promise.reject(new Error(`Mobius socket is not connected for session ${sessionId}`));
171
- }
172
- return socket.send(payload);
173
- }
174
- sendWssRequest(payload, sessionIdOrRequestOptions = this.defaultSessionId, options = {}) {
112
+ sendWssRequest(payload, options = {}) {
175
113
  if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
176
114
  return Promise.reject(new Error('`payload` is required'));
177
115
  }
178
- let sessionId = this.defaultSessionId;
179
- let requestOptions = options;
180
- if (typeof sessionIdOrRequestOptions === 'string') {
181
- sessionId = sessionIdOrRequestOptions;
182
- }
183
- else if (sessionIdOrRequestOptions && typeof sessionIdOrRequestOptions === 'object') {
184
- requestOptions = sessionIdOrRequestOptions;
185
- }
186
- const socket = this.getSocket(sessionId);
187
- if (!socket || !socket.connected) {
188
- return Promise.reject(new Error(`Mobius socket is not connected for session ${sessionId}`));
116
+ if (!this.socket || !this.socket.connected) {
117
+ return Promise.reject(new Error('Mobius socket is not connected'));
189
118
  }
190
- return socket.sendRequest(payload, {
191
- timeout: requestOptions.timeout,
119
+ const requestConfigOptions = {
120
+ timeout: options.timeout,
192
121
  matchesResponse: (response, request) => response?.type === 'response_event' &&
193
122
  response?.subtype === request.type &&
194
123
  response?.trackingId === request.trackingId,
195
124
  getStatusCode: (response) => response?.statusCode,
196
125
  getStatusMessage: (response) => response?.statusMessage,
197
- createError: (response, statusCode, statusMessage) => this._createWssResponseError(response, statusCode, statusMessage),
198
- createTimeoutError: (request) => this._createWssResponseError({
126
+ createError: (response, statusCode, statusMessage) => this.createWssResponseError(response, statusCode, statusMessage),
127
+ createTimeoutError: (request) => this.createWssResponseError({
199
128
  type: 'response_event',
200
129
  subtype: request.type,
201
130
  trackingId: request.trackingId,
202
131
  }, 408, 'Mobius websocket response timed out'),
203
- });
132
+ };
133
+ return this.socket.sendRequest(payload, requestConfigOptions);
204
134
  }
205
135
  isConnected() {
206
136
  return this.connected;
207
137
  }
208
- hasConnectedSockets(sessionId) {
209
- if (sessionId) {
210
- return Boolean(this.sockets.get(sessionId)?.connected);
211
- }
212
- for (const socket of this.sockets.values()) {
213
- if (socket?.connected) {
214
- return true;
215
- }
138
+ connect(webSocketUrl) {
139
+ if (this.connectPromise) {
140
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: connection already in progress, returning existing promise`);
141
+ return this.connectPromise;
216
142
  }
217
- return false;
218
- }
219
- hasConnectingSockets(sessionId = this.defaultSessionId) {
220
- const socket = this.sockets.get(sessionId || this.defaultSessionId);
221
- return Boolean(socket?.connecting);
222
- }
223
- connect(webSocketUrl, sessionId = this.defaultSessionId) {
224
- if (this._connectPromises.has(sessionId)) {
225
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: connection ${sessionId} already in progress, returning existing promise`);
226
- return this._connectPromises.get(sessionId);
227
- }
228
- const sessionSocket = this.sockets.get(sessionId);
229
- if (sessionSocket?.connected || sessionSocket?.connecting) {
230
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: connection ${sessionId} already connected, will not connect again`);
143
+ if (this.socket?.connected || this.socket?.connecting) {
144
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: already connected, will not connect again`);
231
145
  return Promise.resolve();
232
146
  }
233
147
  if (webSocketUrl && this.socketUrl && webSocketUrl !== this.socketUrl) {
234
148
  this.hasEverConnected = false;
235
149
  }
236
- const resolvedUrl = webSocketUrl || this.socketUrl;
237
150
  if (webSocketUrl) {
238
151
  this.socketUrl = webSocketUrl;
239
152
  }
240
153
  this.connecting = true;
241
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: starting connection attempt for ${sessionId}${Number(this.config.initialConnectionMaxRetries) === 0 && !this.hasEverConnected
154
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: starting connection attempt${Number(this.config.initialConnectionMaxRetries) === 0 && !this.hasEverConnected
242
155
  ? ' (initial retries disabled)'
243
156
  : ''}`);
244
157
  const connectPromise = Promise.resolve(this.webex.internal.device.registered || this.webex.internal.device.register())
245
158
  .then(() => {
246
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: connecting ${sessionId}`);
247
- return this._connectWithBackoff(resolvedUrl, sessionId);
159
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: connecting`);
160
+ return this.connectWithBackoff(this.socketUrl);
248
161
  })
249
162
  .finally(() => {
250
- this._connectPromises.delete(sessionId);
163
+ this.connectPromise = undefined;
251
164
  });
252
- this._connectPromises.set(sessionId, connectPromise);
165
+ this.connectPromise = connectPromise;
253
166
  return connectPromise;
254
167
  }
255
- logout() {
256
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: logout() called`);
257
- return this.disconnectAll(this.config.beforeLogoutOptionsCloseReason &&
258
- !normalReconnectReasons.includes(this.config.beforeLogoutOptionsCloseReason)
259
- ? { code: 3050, reason: this.config.beforeLogoutOptionsCloseReason }
260
- : undefined);
261
- }
262
- disconnect(options, sessionId = this.defaultSessionId) {
263
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}#disconnect: connecting state: ${this.connecting}, connected state: ${this.connected}, socket exists: ${!!this
264
- .socket}, options: ${JSON.stringify(options)}`);
265
- const backoffCall = this.backoffCalls.get(sessionId);
266
- if (backoffCall) {
267
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: aborting connection ${sessionId}`);
268
- backoffCall.abort();
269
- this.backoffCalls.delete(sessionId);
270
- }
271
- const shutdownSwitchoverBackoffCall = this._shutdownSwitchoverBackoffCalls.get(sessionId);
272
- if (shutdownSwitchoverBackoffCall) {
273
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: aborting shutdown switchover connection ${sessionId}`);
274
- shutdownSwitchoverBackoffCall.abort();
275
- this._shutdownSwitchoverBackoffCalls.delete(sessionId);
276
- }
277
- this._connectPromises.delete(sessionId);
278
- const sessionSocket = this.sockets.get(sessionId);
279
- this._clearSeenAsyncEventIds(sessionId);
280
- if (!sessionSocket) {
281
- this.connected = this.hasConnectedSockets();
282
- if (!this.hasConnectedSockets()) {
283
- this._stopTokenRefreshTimer();
284
- }
168
+ disconnect(options) {
169
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}#disconnect: connecting state: ${this.connecting},
170
+ connected state: ${this.connected}, socket exists: ${!!this.socket},
171
+ options: ${JSON.stringify(options)}`);
172
+ if (this.backoffCall) {
173
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: aborting connection`);
174
+ this.backoffCall.abort();
175
+ this.backoffCall = undefined;
176
+ }
177
+ if (this.shutdownSwitchoverBackoffCall) {
178
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: aborting shutdown switchover connection`);
179
+ this.shutdownSwitchoverBackoffCall.abort();
180
+ this.shutdownSwitchoverBackoffCall = undefined;
181
+ }
182
+ this.connectPromise = undefined;
183
+ this.seenAsyncEventIds.clear();
184
+ if (!this.socket) {
185
+ this.connected = false;
186
+ this.stopTokenRefreshTimer();
285
187
  return Promise.resolve();
286
188
  }
287
- sessionSocket.removeAllListeners('message');
288
- sessionSocket.connecting = false;
289
- sessionSocket.connected = false;
290
- return Promise.resolve(sessionSocket.close(options || undefined)).finally(() => {
291
- this.connected = this.hasConnectedSockets();
292
- if (!this.hasConnectedSockets()) {
293
- this._stopTokenRefreshTimer();
294
- }
295
- });
296
- }
297
- disconnectAll(options) {
298
- const disconnectPromises = [];
299
- for (const sessionId of this.sockets.keys()) {
300
- disconnectPromises.push(this.disconnect(options, sessionId));
301
- }
302
- return Promise.all(disconnectPromises).then(() => {
189
+ this.socket.removeAllListeners('message');
190
+ this.socket.connecting = false;
191
+ this.socket.connected = false;
192
+ return Promise.resolve(this.socket.close(options || undefined)).finally(() => {
303
193
  this.connected = false;
304
- this.socket = undefined;
305
- this.sockets.clear();
306
- this.backoffCalls.clear();
307
- this._shutdownSwitchoverBackoffCalls.clear();
308
- this._clearSeenAsyncEventIds();
309
- this._stopTokenRefreshTimer();
310
- this._connectPromises.clear();
194
+ this.stopTokenRefreshTimer();
311
195
  });
312
196
  }
313
- processRegistrationStatusEvent(message) {
314
- this.localClusterServiceUrls = message.localClusterServiceUrls;
315
- }
316
- _createWssResponseError(response, statusCode, statusMessage) {
197
+ createWssResponseError(response, statusCode, statusMessage) {
317
198
  const error = new Error(statusMessage || `Mobius websocket request failed with status ${statusCode || 'unknown'}`);
318
199
  error.name = 'MobiusSocketResponseError';
319
200
  error.statusCode = statusCode;
@@ -322,45 +203,36 @@ class MobiusSocket extends EventEmitter {
322
203
  error.trackingId = response?.trackingId;
323
204
  return error;
324
205
  }
325
- _applyOverrides(event) {
326
- if (!event || !event.headers) {
327
- return;
328
- }
329
- const headerKeys = Object.keys(event.headers);
330
- headerKeys.forEach((keyPath) => {
331
- set(event, keyPath, event.headers[keyPath]);
332
- });
333
- }
334
- _prepareUrl(webSocketUrl) {
206
+ prepareUrl(webSocketUrl) {
335
207
  if (!webSocketUrl) {
336
208
  webSocketUrl = this.webex.internal.device.webSocketUrl;
337
209
  }
338
210
  return Promise.resolve(webSocketUrl);
339
211
  }
340
- _attemptConnection(socketUrl, sessionId, callback, options = {}) {
212
+ attemptConnection(socketUrl, callback, options = {}) {
341
213
  const { isShutdownSwitchover = false, onSuccess = null } = options;
342
214
  const socket = new Socket();
343
215
  socket.connecting = true;
344
216
  let newWSUrl;
345
- this._attachSocketEventListeners(socket, sessionId);
217
+ this.attachSocketEventListeners(socket);
346
218
  const backoffCall = isShutdownSwitchover
347
- ? this._shutdownSwitchoverBackoffCalls.get(sessionId)
348
- : this.backoffCalls.get(sessionId);
219
+ ? this.shutdownSwitchoverBackoffCall
220
+ : this.backoffCall;
349
221
  if (!backoffCall) {
350
222
  const mode = isShutdownSwitchover ? 'switchover backoff call' : 'backoffCall';
351
- const msg = `${MOBIUS_SOCKET_NAMESPACE}: prevent socket open when ${mode} no longer defined for ${sessionId}`;
223
+ const msg = `${MOBIUS_SOCKET_NAMESPACE}: prevent socket open when ${mode} no longer defined`;
352
224
  const err = new Error(msg);
353
225
  this.logger.info(msg);
354
226
  callback(err);
355
227
  return Promise.reject(err);
356
228
  }
357
229
  if (!isShutdownSwitchover) {
358
- this.sockets.set(sessionId, socket);
230
+ this.socket = socket;
359
231
  }
360
- return this._prepareAndOpenSocket(socket, socketUrl, sessionId, isShutdownSwitchover)
232
+ return this.prepareAndOpenSocket(socket, socketUrl, isShutdownSwitchover)
361
233
  .then((webSocketUrl) => {
362
234
  newWSUrl = webSocketUrl;
363
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: ${isShutdownSwitchover ? '[shutdown] switchover' : ''} connected to mobius socket, success, action: connected for ${sessionId}, url: ${newWSUrl}`);
235
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: ${isShutdownSwitchover ? '[shutdown] switchover' : ''} connected to mobius socket, success, url: ${newWSUrl}`);
364
236
  if (onSuccess) {
365
237
  onSuccess(socket, webSocketUrl);
366
238
  callback();
@@ -371,48 +243,44 @@ class MobiusSocket extends EventEmitter {
371
243
  })
372
244
  .catch((reason) => {
373
245
  if (isShutdownSwitchover) {
374
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] switchover attempt failed for ${sessionId}`, reason);
246
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] switchover attempt failed`, reason);
375
247
  return callback(reason);
376
248
  }
377
- this.lastError = reason;
378
- const backoffCallNormal = this.backoffCalls.get(sessionId);
249
+ const backoffCallNormal = this.backoffCall;
379
250
  if (reason.code !== 1006 && backoffCallNormal && backoffCallNormal?.getNumRetries() > 0) {
380
- this._emit(sessionId, 'connection_failed', reason, {
381
- sessionId,
251
+ this.emitEvent('connection_failed', reason, {
382
252
  retries: backoffCallNormal?.getNumRetries(),
383
253
  });
384
254
  }
385
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: connection attempt failed for ${sessionId}`, reason, backoffCallNormal?.getNumRetries() === 0 ? reason.stack : '');
255
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: connection attempt failed`, reason, backoffCallNormal?.getNumRetries() === 0 ? reason.stack : '');
386
256
  if (reason instanceof UnknownResponse) {
387
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: received unknown response code for ${sessionId}, refreshing device registration`);
257
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: received unknown response code, refreshing device registration`);
388
258
  return this.webex.internal.device.refresh().then(() => callback(reason));
389
259
  }
390
260
  if (reason instanceof NotAuthorized) {
391
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: received authorization error for ${sessionId}, reauthorizing`);
261
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: received authorization error, reauthorizing`);
392
262
  return this.webex.credentials.refresh({ force: true }).then(() => callback(reason));
393
263
  }
394
264
  if (reason instanceof BadRequest || reason instanceof Forbidden) {
395
- this.logger.warn(`${MOBIUS_SOCKET_NAMESPACE}: received unrecoverable response from ${MOBIUS_SOCKET_NAMESPACE} for ${sessionId}`);
265
+ this.logger.warn(`${MOBIUS_SOCKET_NAMESPACE}: received unrecoverable response from ${MOBIUS_SOCKET_NAMESPACE}`);
396
266
  backoffCallNormal?.abort();
397
267
  return callback(reason);
398
268
  }
399
269
  return callback(reason);
400
270
  })
401
271
  .catch((reason) => {
402
- this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: failed to handle connection failure for ${sessionId}`, reason);
272
+ this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: failed to handle connection failure`, reason);
403
273
  callback(reason);
404
274
  });
405
275
  }
406
- _prepareAndOpenSocket(socket, socketUrl, sessionId, isShutdownSwitchover = false) {
276
+ prepareAndOpenSocket(socket, socketUrl, isShutdownSwitchover = false) {
407
277
  const logPrefix = isShutdownSwitchover ? '[shutdown] switchover' : 'connection';
408
- return Promise.all([this._prepareUrl(socketUrl), this.webex.credentials.getUserToken()]).then(([webSocketUrl, token]) => {
278
+ return Promise.all([this.prepareUrl(socketUrl), this.webex.credentials.getUserToken()]).then(([webSocketUrl, token]) => {
409
279
  let options = {
410
280
  forceCloseDelay: this.config.forceCloseDelay,
411
281
  wssResponseTimeout: this.config.wssResponseTimeout,
412
- skipAckEventId: this.config.skipAckEventId,
413
- skipAckEventType: this.config.skipAckEventType,
414
282
  token: normalizeMobiusAuthToken(token.toString()),
415
- refreshToken: () => this._refreshToken(),
283
+ refreshToken: () => this.refreshToken(),
416
284
  trackingId: `${this.webex.sessionId}_${Date.now()}`,
417
285
  logger: this.logger,
418
286
  };
@@ -423,13 +291,14 @@ class MobiusSocket extends EventEmitter {
423
291
  this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: ${customOptionsMsg}`);
424
292
  options = { ...options, ...this.webex.config.defaultMobiusSocketOptions };
425
293
  }
426
- this.sockets.set(sessionId, socket);
427
- this.socket = this.sockets.get(this.defaultSessionId);
428
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE} ${logPrefix} url for ${sessionId}: ${webSocketUrl}`);
294
+ if (!isShutdownSwitchover) {
295
+ this.socket = socket;
296
+ }
297
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE} ${logPrefix} url: ${webSocketUrl}`);
429
298
  return socket.open(webSocketUrl, options).then(() => webSocketUrl);
430
299
  });
431
300
  }
432
- _connectWithBackoff(webSocketUrl, sessionId, context = {}) {
301
+ connectWithBackoff(webSocketUrl, context = {}) {
433
302
  const { isShutdownSwitchover = false, attemptOptions = {} } = context;
434
303
  return new Promise((resolve, reject) => {
435
304
  let call;
@@ -438,44 +307,43 @@ class MobiusSocket extends EventEmitter {
438
307
  ? null
439
308
  : Number(this.config.initialConnectionMaxRetries);
440
309
  const isInitialConnectWithoutRetries = isInitialConnect && initialRetryLimit === 0;
441
- const onComplete = (err, sid = sessionId) => {
310
+ const onComplete = (err) => {
442
311
  if (isShutdownSwitchover) {
443
- this._shutdownSwitchoverBackoffCalls.delete(sid);
312
+ this.shutdownSwitchoverBackoffCall = undefined;
444
313
  }
445
314
  else {
446
- this.backoffCalls.delete(sid);
315
+ this.backoffCall = undefined;
447
316
  }
448
- const sessionSocket = this.sockets.get(sid);
449
317
  if (err) {
450
318
  const msg = isShutdownSwitchover
451
319
  ? `[shutdown] switchover failed after ${call.getNumRetries()} retries`
452
320
  : `failed to connect after ${call.getNumRetries()} retries`;
453
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: ${msg}; log statement about next retry was inaccurate; ${err}`);
454
- if (sessionSocket) {
455
- sessionSocket.connecting = false;
456
- sessionSocket.connected = false;
321
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: ${msg}; ${err}`);
322
+ if (!isShutdownSwitchover && this.socket) {
323
+ this.socket.connecting = false;
324
+ this.socket.connected = false;
457
325
  }
458
326
  return reject(err);
459
327
  }
460
- if (sessionSocket) {
461
- sessionSocket.connecting = false;
462
- sessionSocket.connected = true;
328
+ if (!isShutdownSwitchover && this.socket) {
329
+ this.socket.connecting = false;
330
+ this.socket.connected = true;
463
331
  }
464
332
  if (!isShutdownSwitchover) {
465
- this.connecting = this.hasConnectingSockets();
466
- this.connected = this.hasConnectedSockets();
333
+ this.connecting = false;
334
+ this.connected = true;
467
335
  this.hasEverConnected = true;
468
- this._startTokenRefreshTimer();
469
- this._emit(sid, 'online');
336
+ this.startTokenRefreshTimer();
337
+ this.emitEvent('online');
470
338
  }
471
339
  return resolve();
472
340
  };
473
341
  call = backoff.call((callback) => {
474
342
  const attemptNum = call.getNumRetries();
475
343
  const attemptLogPrefix = isShutdownSwitchover ? '[shutdown] switchover' : 'connection';
476
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: executing ${attemptLogPrefix} attempt ${attemptNum} for ${sessionId}`);
477
- this._attemptConnection(webSocketUrl, sessionId, callback, attemptOptions);
478
- }, (err) => onComplete(err, sessionId));
344
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: executing ${attemptLogPrefix} attempt ${attemptNum}`);
345
+ this.attemptConnection(webSocketUrl, callback, attemptOptions);
346
+ }, (err) => onComplete(err));
479
347
  call.setStrategy(new backoff.ExponentialStrategy({
480
348
  initialDelay: this.config.backoffTimeReset,
481
349
  maxDelay: this.config.backoffTimeMax,
@@ -490,94 +358,70 @@ class MobiusSocket extends EventEmitter {
490
358
  call.failAfter(this.config.maxRetries);
491
359
  }
492
360
  if (isShutdownSwitchover) {
493
- this._shutdownSwitchoverBackoffCalls.set(sessionId, call);
361
+ this.shutdownSwitchoverBackoffCall = call;
494
362
  }
495
363
  else {
496
- this.backoffCalls.set(sessionId, call);
364
+ this.backoffCall = call;
497
365
  }
498
366
  call.on('abort', () => {
499
367
  const msg = isShutdownSwitchover ? 'Shutdown Switchover' : 'Connection';
500
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: ${msg} aborted for ${sessionId}`);
501
- reject(new Error(`MobiusSocket ${msg} Aborted for ${sessionId}`));
368
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: ${msg} aborted`);
369
+ reject(new Error(`MobiusSocket ${msg} Aborted`));
502
370
  });
503
371
  call.on('callback', (err) => {
504
372
  if (err) {
505
373
  if (isInitialConnectWithoutRetries) {
506
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: initial connect failed for ${sessionId}; retries already disabled`);
374
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: initial connect failed; retries already disabled`);
507
375
  return;
508
376
  }
509
377
  const number = call.getNumRetries();
510
378
  const delay = Math.min(call.strategy_.nextBackoffDelay_, this.config.backoffTimeMax);
511
379
  const callbackLogPrefix = isShutdownSwitchover ? '[shutdown] switchover' : '';
512
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: ${callbackLogPrefix} failed to connect; attempting retry ${number + 1} in ${delay} ms for ${sessionId}`);
380
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: ${callbackLogPrefix} failed to connect; attempting retry ${number + 1} in ${delay} ms`);
513
381
  if (process.env.NODE_ENV === 'development') {
514
382
  this.logger.debug(`${MOBIUS_SOCKET_NAMESPACE}: `, err, err.stack);
515
383
  }
516
384
  return;
517
385
  }
518
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: connected ${sessionId}`);
386
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: connected`);
519
387
  });
520
388
  call.start();
521
389
  });
522
390
  }
523
- _emit(sessionId, eventName, ...args) {
391
+ emitEvent(eventName, ...args) {
524
392
  try {
525
- if (!sessionId || !eventName) {
393
+ if (!eventName) {
526
394
  return;
527
395
  }
528
- const suffix = sessionId === this.defaultSessionId ? '' : `:${sessionId}`;
529
- this.emit(`${eventName}${suffix}`, ...args);
396
+ this.emit(eventName, ...args);
530
397
  }
531
398
  catch (error) {
532
- try {
533
- this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: error occurred in event handler:`, error, ' with args: ', [sessionId, eventName, ...args]);
534
- }
535
- catch (logError) {
536
- console.error('MobiusSocket _emit error handling failed:', logError);
537
- }
538
- }
539
- }
540
- _getEventHandlers(eventType) {
541
- if (!eventType) {
542
- return [];
543
- }
544
- const [namespace, name] = eventType.split('.');
545
- const handlers = [];
546
- if (!this.webex[namespace] && !this.webex.internal[namespace]) {
547
- return handlers;
548
- }
549
- const handlerName = camelCase(`process_${name}_event`);
550
- if ((this.webex[namespace] || this.webex.internal[namespace])[handlerName]) {
551
- handlers.push({
552
- name: handlerName,
553
- namespace,
554
- });
399
+ this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: error occurred in event handler:`, error, ' with args: ', [eventName, ...args]);
555
400
  }
556
- return handlers;
557
401
  }
558
- _startTokenRefreshTimer() {
559
- if (this._tokenRefreshTimer || !this.hasConnectedSockets()) {
402
+ startTokenRefreshTimer() {
403
+ if (this.tokenRefreshTimer || !this.connected) {
560
404
  return;
561
405
  }
562
- this._tokenRefreshTimer = setInterval(() => {
563
- this._refreshToken().catch((error) => {
406
+ this.tokenRefreshTimer = setInterval(() => {
407
+ this.refreshToken().catch((error) => {
564
408
  this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: periodic token refresh failed`, error);
565
409
  });
566
410
  }, TOKEN_REFRESH_INTERVAL_MS);
567
411
  }
568
- _stopTokenRefreshTimer() {
569
- if (!this._tokenRefreshTimer) {
412
+ stopTokenRefreshTimer() {
413
+ if (!this.tokenRefreshTimer) {
570
414
  return;
571
415
  }
572
- clearInterval(this._tokenRefreshTimer);
573
- this._tokenRefreshTimer = undefined;
416
+ clearInterval(this.tokenRefreshTimer);
417
+ this.tokenRefreshTimer = undefined;
574
418
  }
575
- _refreshToken() {
576
- if (this._tokenRefreshInFlight) {
577
- return this._tokenRefreshInFlight;
419
+ refreshToken() {
420
+ if (this.tokenRefreshInFlight) {
421
+ return this.tokenRefreshInFlight;
578
422
  }
579
- if (!this.hasConnectedSockets()) {
580
- this._stopTokenRefreshTimer();
423
+ if (!this.connected) {
424
+ this.stopTokenRefreshTimer();
581
425
  return Promise.resolve();
582
426
  }
583
427
  const tokenPromise = this.webex.credentials.canRefresh
@@ -585,176 +429,145 @@ class MobiusSocket extends EventEmitter {
585
429
  .refresh({ force: true })
586
430
  .then(() => this.webex.credentials.getUserToken())
587
431
  : this.webex.credentials.getUserToken();
588
- this._tokenRefreshInFlight = tokenPromise
432
+ this.tokenRefreshInFlight = tokenPromise
589
433
  .then((token) => {
590
434
  if (!token) {
591
435
  throw new Error('Mobius token refresh did not return a token');
592
436
  }
593
437
  const refreshedToken = normalizeMobiusAuthToken(token.toString());
594
- const authPayloadPromises = [];
595
- for (const socket of this.sockets.values()) {
596
- if (socket?.connected) {
597
- authPayloadPromises.push(socket.refresh(refreshedToken));
598
- }
438
+ if (this.socket?.connected) {
439
+ return this.socket.refresh(refreshedToken);
599
440
  }
600
- return Promise.all(authPayloadPromises);
441
+ return undefined;
601
442
  })
602
443
  .catch((error) => {
603
- this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: failed to refresh/re-auth Mobius sockets`, error);
444
+ this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: failed to refresh/re-auth Mobius socket`, error);
604
445
  throw error;
605
446
  })
606
447
  .finally(() => {
607
- this._tokenRefreshInFlight = undefined;
448
+ this.tokenRefreshInFlight = undefined;
608
449
  });
609
- return this._tokenRefreshInFlight;
450
+ return this.tokenRefreshInFlight;
610
451
  }
611
- _onclose(sessionId, event, sourceSocket) {
452
+ onclose(event, sourceSocket) {
612
453
  try {
613
454
  const reason = event.reason && event.reason.toLowerCase();
614
- const sessionSocket = this.sockets.get(sessionId);
615
455
  let socketUrl;
616
- event.sessionId = sessionId;
617
- const isActiveSocket = sourceSocket === sessionSocket;
456
+ const isActiveSocket = sourceSocket === this.socket;
618
457
  if (sourceSocket) {
619
458
  socketUrl = sourceSocket.url;
620
459
  }
621
- this.sockets.delete(sessionId);
622
460
  if (isActiveSocket) {
623
- if (sessionSocket) {
624
- sessionSocket.removeAllListeners();
625
- if (sessionId === this.defaultSessionId) {
626
- this.socket = undefined;
627
- }
628
- this._emit(sessionId, 'offline', event);
629
- }
630
- this.connecting = this.hasConnectingSockets();
631
- this.connected = this.hasConnectedSockets();
632
- if (!this.hasConnectedSockets()) {
633
- this._stopTokenRefreshTimer();
461
+ if (this.socket) {
462
+ this.socket.removeAllListeners();
463
+ this.socket = undefined;
464
+ this.emitEvent('offline', event);
634
465
  }
466
+ this.connecting = false;
467
+ this.connected = false;
468
+ this.stopTokenRefreshTimer();
635
469
  }
636
470
  else {
637
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] non-active socket closed, code=${event.code} for ${sessionId}`);
471
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] non-active socket closed, code=${event.code}`);
638
472
  if (sourceSocket) {
639
473
  sourceSocket.removeAllListeners();
640
474
  }
641
475
  }
642
476
  switch (event.code) {
643
477
  case 1003:
644
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: service rejected last message for ${sessionId}; will not reconnect: ${event.reason}`);
478
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: service rejected last message; will not reconnect: ${event.reason}`);
645
479
  if (isActiveSocket)
646
- this._emit(sessionId, 'offline.permanent', event);
480
+ this.emitEvent('offline.permanent', event);
647
481
  break;
648
482
  case 4000:
649
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: socket ${sessionId} replaced; will not reconnect`);
483
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: socket replaced; will not reconnect`);
650
484
  if (isActiveSocket)
651
- this._emit(sessionId, 'offline.replaced', event);
485
+ this.emitEvent('offline.replaced', event);
652
486
  break;
653
487
  case 4001:
654
488
  if (isActiveSocket) {
655
- this.logger.warn(`${MOBIUS_SOCKET_NAMESPACE}: active socket closed with 4001; shutdown switchover failed for ${sessionId}`);
656
- this._emit(sessionId, 'offline.permanent', event);
489
+ this.logger.warn(`${MOBIUS_SOCKET_NAMESPACE}: active socket closed with 4001; shutdown switchover failed`);
490
+ this.emitEvent('offline.permanent', event);
657
491
  }
658
492
  else {
659
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: old socket closed with 4001 (replaced during shutdown); no reconnect needed for ${sessionId}`);
660
- this._emit(sessionId, 'offline.replaced', event);
493
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: old socket closed with 4001 (replaced during shutdown); no reconnect needed`);
494
+ this.emitEvent('offline.replaced', event);
661
495
  }
662
496
  break;
663
497
  case 1001:
664
498
  case 1005:
665
499
  case 1006:
666
500
  case 1011:
667
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: socket ${sessionId} disconnected; reconnecting`);
501
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: socket disconnected; reconnecting`);
668
502
  if (isActiveSocket) {
669
- this._emit(sessionId, 'offline.transient', event);
670
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] reconnecting active socket to recover for ${sessionId}`);
671
- this._reconnect(socketUrl, sessionId);
503
+ this.emitEvent('offline.transient', event);
504
+ this.reconnect(socketUrl);
672
505
  }
673
506
  break;
674
507
  case 1000:
675
508
  case 3050:
676
509
  if (normalReconnectReasons.includes(reason)) {
677
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: socket ${sessionId} disconnected; reconnecting`);
510
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: socket disconnected; reconnecting`);
678
511
  if (isActiveSocket) {
679
- this._emit(sessionId, 'offline.transient', event);
680
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] reconnecting due to normal close for ${sessionId}`);
681
- this._reconnect(socketUrl, sessionId);
512
+ this.emitEvent('offline.transient', event);
513
+ this.reconnect(socketUrl);
682
514
  }
683
515
  }
684
516
  else {
685
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: socket ${sessionId} disconnected; will not reconnect: ${event.reason}`);
517
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: socket disconnected; will not reconnect: ${event.reason}`);
686
518
  if (isActiveSocket)
687
- this._emit(sessionId, 'offline.permanent', event);
519
+ this.emitEvent('offline.permanent', event);
688
520
  }
689
521
  break;
690
522
  default:
691
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: socket ${sessionId} disconnected unexpectedly; will not reconnect`);
523
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: socket disconnected unexpectedly; will not reconnect`);
692
524
  if (isActiveSocket)
693
- this._emit(sessionId, 'offline.permanent', event);
525
+ this.emitEvent('offline.permanent', event);
694
526
  }
695
527
  }
696
528
  catch (error) {
697
- this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: error occurred in close handler for ${sessionId}`, error);
529
+ this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: error occurred in close handler`, error);
698
530
  }
699
531
  }
700
- _onmessage(sessionId, event) {
701
- this._setTimeOffset(sessionId, event);
532
+ onmessage(event) {
702
533
  const envelope = event.data;
703
- if (process.env.ENABLE_MERCURY_LOGGING) {
704
- this.logger.debug(`${MOBIUS_SOCKET_NAMESPACE}: message envelope from ${sessionId}: `, envelope);
534
+ if (process.env.ENABLE_MOBIUS_LOGGING) {
535
+ this.logger.debug(`${MOBIUS_SOCKET_NAMESPACE}: message envelope: `, envelope);
705
536
  }
706
- envelope.sessionId = sessionId;
707
537
  if (envelope && envelope.type === 'shutdown') {
708
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] imminent shutdown message received for ${sessionId}`);
709
- this._emit(sessionId, 'event:mercury_shutdown_imminent', envelope);
710
- this._handleImminentShutdown(sessionId);
538
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: [shutdown] imminent shutdown message received`);
539
+ this.emitEvent('event:mobius_shutdown_imminent', envelope);
540
+ this.handleImminentShutdown();
711
541
  return Promise.resolve();
712
542
  }
713
- if (this._trackAsyncEventAndShouldSuppressDuplicate(sessionId, envelope)) {
543
+ if (this.trackAsyncEventAndShouldSuppressDuplicate(envelope)) {
714
544
  return Promise.resolve();
715
545
  }
716
546
  if (envelope.type) {
717
- this._emit(sessionId, `event:${envelope.type}`, envelope);
547
+ this.emitEvent(`event:${envelope.type}`, envelope);
718
548
  }
719
- envelope.sessionId = sessionId;
720
549
  const data = envelope.data || envelope;
721
- this._applyOverrides(data);
722
550
  const eventType = data?.eventType || envelope.eventType;
723
551
  if (!eventType) {
724
- this._emit(sessionId, 'event', envelope);
552
+ this.emitEvent('event', envelope);
725
553
  return Promise.resolve();
726
554
  }
727
- return this._getEventHandlers(eventType)
728
- .reduce((promise, handler) => promise.then(() => {
729
- const { namespace, name } = handler;
730
- return new Promise((resolve) => {
731
- resolve((this.webex[namespace] || this.webex.internal[namespace])[name](data));
732
- }).catch((reason) => this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: error occurred in autowired event handler for ${eventType} from ${sessionId}`, reason));
733
- }), Promise.resolve())
734
- .then(() => {
735
- this._emit(sessionId, 'event', envelope);
555
+ try {
556
+ this.emitEvent('event', envelope);
736
557
  const [namespace] = eventType.split('.');
737
- if (namespace === eventType) {
738
- this._emit(sessionId, `event:${namespace}`, envelope);
558
+ this.emitEvent(`event:${namespace}`, envelope);
559
+ if (namespace !== eventType) {
560
+ this.emitEvent(`event:${eventType}`, envelope);
739
561
  }
740
- else {
741
- this._emit(sessionId, `event:${namespace}`, envelope);
742
- this._emit(sessionId, `event:${eventType}`, envelope);
743
- }
744
- })
745
- .catch((reason) => {
746
- this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: error occurred processing socket message from ${sessionId}`, reason);
747
- });
748
- }
749
- _setTimeOffset(sessionId, event) {
750
- const { wsWriteTimestamp } = event.data;
751
- if (typeof wsWriteTimestamp === 'number' && wsWriteTimestamp > 0) {
752
- this.mercuryTimeOffset = Date.now() - wsWriteTimestamp;
753
562
  }
563
+ catch (reason) {
564
+ this.logger.error(`${MOBIUS_SOCKET_NAMESPACE}: error occurred processing socket message`, reason);
565
+ }
566
+ return Promise.resolve();
754
567
  }
755
- _reconnect(webSocketUrl, sessionId = this.defaultSessionId) {
756
- this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: reconnecting ${sessionId}`);
757
- return this.connect(webSocketUrl || this.socketUrl, sessionId);
568
+ reconnect(webSocketUrl) {
569
+ this.logger.info(`${MOBIUS_SOCKET_NAMESPACE}: reconnecting`);
570
+ return this.connect(webSocketUrl || this.socketUrl);
758
571
  }
759
572
  }
760
573
  export default MobiusSocket;