@stream-io/video-client 1.27.2 → 1.27.4
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/CHANGELOG.md +12 -0
- package/dist/index.browser.es.js +195 -148
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +195 -148
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +195 -148
- package/dist/index.es.js.map +1 -1
- package/dist/src/StreamSfuClient.d.ts +0 -1
- package/dist/src/helpers/browsers.d.ts +7 -0
- package/dist/src/rtc/signal.d.ts +2 -0
- package/package.json +1 -1
- package/src/StreamSfuClient.ts +19 -14
- package/src/helpers/__tests__/browsers.test.ts +191 -0
- package/src/helpers/browsers.ts +25 -0
- package/src/helpers/client-details.ts +18 -3
- package/src/rtc/signal.ts +10 -6
|
@@ -139,7 +139,6 @@ export declare class StreamSfuClient {
|
|
|
139
139
|
*/
|
|
140
140
|
constructor({ dispatcher, credentials, sessionId, cid, tag, joinResponseTimeout, onSignalClose, streamClient, enableTracing, }: StreamSfuClientConstructor);
|
|
141
141
|
private createWebSocket;
|
|
142
|
-
private cleanUpWebSocket;
|
|
143
142
|
get isHealthy(): boolean;
|
|
144
143
|
get joinTask(): Promise<JoinResponse>;
|
|
145
144
|
private handleWebSocketClose;
|
|
@@ -10,3 +10,10 @@ export declare const isFirefox: () => boolean;
|
|
|
10
10
|
* Checks whether the current browser is Google Chrome.
|
|
11
11
|
*/
|
|
12
12
|
export declare const isChrome: () => boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Checks whether the current browser is among the list of first-class supported browsers.
|
|
15
|
+
* This includes Chrome, Edge, Firefox, and Safari.
|
|
16
|
+
*
|
|
17
|
+
* Although the Stream Video SDK may work in other browsers, these are the ones we officially support.
|
|
18
|
+
*/
|
|
19
|
+
export declare const isSupportedBrowser: () => Promise<boolean>;
|
package/dist/src/rtc/signal.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { DispatchableMessage, SfuEventKinds } from './Dispatcher';
|
|
2
|
+
import { Tracer } from '../stats';
|
|
2
3
|
export declare const createWebSocketSignalChannel: (opts: {
|
|
3
4
|
endpoint: string;
|
|
4
5
|
onMessage: <K extends SfuEventKinds>(message: DispatchableMessage<K>) => void;
|
|
5
6
|
tag: string;
|
|
7
|
+
tracer: Tracer | undefined;
|
|
6
8
|
}) => WebSocket;
|
package/package.json
CHANGED
package/src/StreamSfuClient.ts
CHANGED
|
@@ -274,6 +274,7 @@ export class StreamSfuClient {
|
|
|
274
274
|
this.signalWs = createWebSocketSignalChannel({
|
|
275
275
|
tag: this.tag,
|
|
276
276
|
endpoint: `${this.credentials.server.ws_endpoint}?${new URLSearchParams(params).toString()}`,
|
|
277
|
+
tracer: this.tracer,
|
|
277
278
|
onMessage: (message) => {
|
|
278
279
|
this.lastMessageTimestamp = new Date();
|
|
279
280
|
this.scheduleConnectionCheck();
|
|
@@ -285,10 +286,14 @@ export class StreamSfuClient {
|
|
|
285
286
|
},
|
|
286
287
|
});
|
|
287
288
|
|
|
289
|
+
let timeoutId: NodeJS.Timeout;
|
|
288
290
|
this.signalReady = makeSafePromise(
|
|
289
291
|
Promise.race<WebSocket>([
|
|
290
292
|
new Promise((resolve, reject) => {
|
|
293
|
+
let didOpen = false;
|
|
291
294
|
const onOpen = () => {
|
|
295
|
+
didOpen = true;
|
|
296
|
+
clearTimeout(timeoutId);
|
|
292
297
|
this.signalWs.removeEventListener('open', onOpen);
|
|
293
298
|
resolve(this.signalWs);
|
|
294
299
|
};
|
|
@@ -298,28 +303,28 @@ export class StreamSfuClient {
|
|
|
298
303
|
this.signalWs.addEventListener('close', (e) => {
|
|
299
304
|
this.handleWebSocketClose(e);
|
|
300
305
|
// Normally, this shouldn't have any effect, because WS should never emit 'close'
|
|
301
|
-
// before emitting 'open'. However,
|
|
302
|
-
// want to leave signalReady in pending state.
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
+
// before emitting 'open'. However, stranger things have happened, and we don't
|
|
307
|
+
// want to leave signalReady in a pending state.
|
|
308
|
+
const message = didOpen
|
|
309
|
+
? `SFU WS closed: ${e.code} ${e.reason}`
|
|
310
|
+
: `SFU WS connection can't be established: ${e.code} ${e.reason}`;
|
|
311
|
+
this.tracer?.trace('signal.close', message);
|
|
312
|
+
clearTimeout(timeoutId);
|
|
313
|
+
reject(new Error(message));
|
|
306
314
|
});
|
|
307
315
|
}),
|
|
308
316
|
|
|
309
317
|
new Promise((resolve, reject) => {
|
|
310
|
-
setTimeout(
|
|
311
|
-
|
|
312
|
-
this.
|
|
313
|
-
|
|
318
|
+
timeoutId = setTimeout(() => {
|
|
319
|
+
const message = `SFU WS connection failed to open after ${this.joinResponseTimeout}ms`;
|
|
320
|
+
this.tracer?.trace('signal.timeout', message);
|
|
321
|
+
reject(new Error(message));
|
|
322
|
+
}, this.joinResponseTimeout);
|
|
314
323
|
}),
|
|
315
324
|
]),
|
|
316
325
|
);
|
|
317
326
|
};
|
|
318
327
|
|
|
319
|
-
private cleanUpWebSocket = () => {
|
|
320
|
-
this.signalWs.removeEventListener('close', this.handleWebSocketClose);
|
|
321
|
-
};
|
|
322
|
-
|
|
323
328
|
get isHealthy() {
|
|
324
329
|
return (
|
|
325
330
|
this.signalWs.readyState === WebSocket.OPEN &&
|
|
@@ -343,7 +348,7 @@ export class StreamSfuClient {
|
|
|
343
348
|
if (this.signalWs.readyState === WebSocket.OPEN) {
|
|
344
349
|
this.logger('debug', `Closing SFU WS connection: ${code} - ${reason}`);
|
|
345
350
|
this.signalWs.close(code, `js-client: ${reason}`);
|
|
346
|
-
this.
|
|
351
|
+
this.signalWs.removeEventListener('close', this.handleWebSocketClose);
|
|
347
352
|
}
|
|
348
353
|
this.dispose();
|
|
349
354
|
};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { isChrome, isFirefox, isSafari, isSupportedBrowser } from '../browsers';
|
|
3
|
+
import { getClientDetails } from '../client-details';
|
|
4
|
+
import { ClientDetails } from '../../gen/video/sfu/models/models';
|
|
5
|
+
|
|
6
|
+
describe('browsers', () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
Object.defineProperty(globalThis, 'navigator', {
|
|
9
|
+
value: { userAgent: '' },
|
|
10
|
+
writable: true,
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
describe('isSafari', () => {
|
|
15
|
+
it('should return false if navigator is undefined', () => {
|
|
16
|
+
expect(isSafari()).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should return true for Safari user agent', () => {
|
|
20
|
+
// @ts-expect-error - mocking navigator
|
|
21
|
+
globalThis.navigator.userAgent =
|
|
22
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15';
|
|
23
|
+
expect(isSafari()).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should return false for Chrome user agent', () => {
|
|
27
|
+
// @ts-expect-error - mocking navigator
|
|
28
|
+
globalThis.navigator.userAgent =
|
|
29
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36';
|
|
30
|
+
expect(isSafari()).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('isFirefox', () => {
|
|
35
|
+
it('should return false if navigator is undefined', () => {
|
|
36
|
+
expect(isFirefox()).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should return true for Firefox user agent', () => {
|
|
40
|
+
// @ts-expect-error - mocking navigator
|
|
41
|
+
globalThis.navigator.userAgent =
|
|
42
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0';
|
|
43
|
+
expect(isFirefox()).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should return false for Chrome user agent', () => {
|
|
47
|
+
// @ts-expect-error - mocking navigator
|
|
48
|
+
globalThis.navigator.userAgent =
|
|
49
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36';
|
|
50
|
+
expect(isFirefox()).toBe(false);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('isChrome', () => {
|
|
55
|
+
it('should return false if navigator is undefined', () => {
|
|
56
|
+
expect(isChrome()).toBe(false);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should return true for Chrome user agent', () => {
|
|
60
|
+
// @ts-expect-error - mocking navigator
|
|
61
|
+
globalThis.navigator.userAgent =
|
|
62
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36';
|
|
63
|
+
expect(isChrome()).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should return false for Firefox user agent', () => {
|
|
67
|
+
// @ts-expect-error - mocking navigator
|
|
68
|
+
globalThis.navigator.userAgent =
|
|
69
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0';
|
|
70
|
+
expect(isChrome()).toBe(false);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe('isSupportedBrowser', () => {
|
|
75
|
+
vi.mock('../client-details', () => ({
|
|
76
|
+
getClientDetails: vi.fn(),
|
|
77
|
+
}));
|
|
78
|
+
|
|
79
|
+
it('should return false if browser is undefined', async () => {
|
|
80
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
81
|
+
browser: undefined,
|
|
82
|
+
} as ClientDetails);
|
|
83
|
+
expect(await isSupportedBrowser()).toBe(false);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should return true for supported Chrome version', async () => {
|
|
87
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
88
|
+
browser: { name: 'Chrome', version: '124' },
|
|
89
|
+
} as ClientDetails);
|
|
90
|
+
expect(await isSupportedBrowser()).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should return true for supported Chrome detailed version', async () => {
|
|
94
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
95
|
+
browser: { name: 'Chrome', version: '124.0.7204.158' },
|
|
96
|
+
} as ClientDetails);
|
|
97
|
+
expect(await isSupportedBrowser()).toBe(true);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should return false for unsupported Chrome version', async () => {
|
|
101
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
102
|
+
browser: { name: 'Chrome', version: '123' },
|
|
103
|
+
} as ClientDetails);
|
|
104
|
+
expect(await isSupportedBrowser()).toBe(false);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should return false for unsupported Chrome detailed version', async () => {
|
|
108
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
109
|
+
browser: { name: 'Chrome', version: '123.0.1234.99' },
|
|
110
|
+
} as ClientDetails);
|
|
111
|
+
expect(await isSupportedBrowser()).toBe(false);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should return true for supported Edge version', async () => {
|
|
115
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
116
|
+
browser: { name: 'Edge', version: '124' },
|
|
117
|
+
} as ClientDetails);
|
|
118
|
+
expect(await isSupportedBrowser()).toBe(true);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('should return false for unsupported Edge version', async () => {
|
|
122
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
123
|
+
browser: { name: 'Edge', version: '123' },
|
|
124
|
+
} as ClientDetails);
|
|
125
|
+
expect(await isSupportedBrowser()).toBe(false);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('should return true for supported Firefox version', async () => {
|
|
129
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
130
|
+
browser: { name: 'Firefox', version: '124' },
|
|
131
|
+
} as ClientDetails);
|
|
132
|
+
expect(await isSupportedBrowser()).toBe(true);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should return false for unsupported Firefox version', async () => {
|
|
136
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
137
|
+
browser: { name: 'Firefox', version: '123' },
|
|
138
|
+
} as ClientDetails);
|
|
139
|
+
expect(await isSupportedBrowser()).toBe(false);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('should return true for supported Safari version', async () => {
|
|
143
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
144
|
+
browser: { name: 'Safari', version: '17' },
|
|
145
|
+
} as ClientDetails);
|
|
146
|
+
expect(await isSupportedBrowser()).toBe(true);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('should return false for unsupported Safari version', async () => {
|
|
150
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
151
|
+
browser: { name: 'Safari', version: '16' },
|
|
152
|
+
} as ClientDetails);
|
|
153
|
+
expect(await isSupportedBrowser()).toBe(false);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should return true for supported WebKit version (WebView on iOS)', async () => {
|
|
157
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
158
|
+
browser: { name: 'WebKit', version: '605' },
|
|
159
|
+
} as ClientDetails);
|
|
160
|
+
expect(await isSupportedBrowser()).toBe(true);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('should return false for unsupported WebKit version (WebView on iOS)', async () => {
|
|
164
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
165
|
+
browser: { name: 'WebKit', version: '604' },
|
|
166
|
+
} as ClientDetails);
|
|
167
|
+
expect(await isSupportedBrowser()).toBe(false);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('should return true for supported WebView version (WebView on Android)', async () => {
|
|
171
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
172
|
+
browser: { name: 'WebView', version: '124' },
|
|
173
|
+
} as ClientDetails);
|
|
174
|
+
expect(await isSupportedBrowser()).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('should return false for unsupported WebView version (WebView on Android)', async () => {
|
|
178
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
179
|
+
browser: { name: 'WebView', version: '123' },
|
|
180
|
+
} as ClientDetails);
|
|
181
|
+
expect(await isSupportedBrowser()).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('should return false for unsupported browser', async () => {
|
|
185
|
+
vi.mocked(getClientDetails).mockResolvedValue({
|
|
186
|
+
browser: { name: 'Opera', version: '78' },
|
|
187
|
+
} as ClientDetails);
|
|
188
|
+
expect(await isSupportedBrowser()).toBe(false);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
});
|
package/src/helpers/browsers.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getClientDetails } from './client-details';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Checks whether the current browser is Safari.
|
|
3
5
|
*/
|
|
@@ -21,3 +23,26 @@ export const isChrome = () => {
|
|
|
21
23
|
if (typeof navigator === 'undefined') return false;
|
|
22
24
|
return navigator.userAgent?.includes('Chrome');
|
|
23
25
|
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Checks whether the current browser is among the list of first-class supported browsers.
|
|
29
|
+
* This includes Chrome, Edge, Firefox, and Safari.
|
|
30
|
+
*
|
|
31
|
+
* Although the Stream Video SDK may work in other browsers, these are the ones we officially support.
|
|
32
|
+
*/
|
|
33
|
+
export const isSupportedBrowser = async (): Promise<boolean> => {
|
|
34
|
+
const { browser } = await getClientDetails();
|
|
35
|
+
if (!browser) return false; // we aren't running in a browser
|
|
36
|
+
|
|
37
|
+
const name = browser.name.toLowerCase();
|
|
38
|
+
const [major] = browser.version.split('.');
|
|
39
|
+
const version = parseInt(major, 10);
|
|
40
|
+
return (
|
|
41
|
+
(name.includes('chrome') && version >= 124) ||
|
|
42
|
+
(name.includes('edge') && version >= 124) ||
|
|
43
|
+
(name.includes('firefox') && version >= 124) ||
|
|
44
|
+
(name.includes('safari') && version >= 17) ||
|
|
45
|
+
(name.includes('webkit') && version >= 605) || // WebView on iOS
|
|
46
|
+
(name.includes('webview') && version >= 124) // WebView on Android
|
|
47
|
+
);
|
|
48
|
+
};
|
|
@@ -143,13 +143,18 @@ export const getClientDetails = async (): Promise<ClientDetails> => {
|
|
|
143
143
|
// @ts-expect-error - userAgentData is not yet in the TS types
|
|
144
144
|
const userAgentDataApi = navigator.userAgentData;
|
|
145
145
|
let userAgentData:
|
|
146
|
-
| {
|
|
146
|
+
| {
|
|
147
|
+
platform?: string;
|
|
148
|
+
platformVersion?: string;
|
|
149
|
+
fullVersionList?: Array<{ brand: string; version: string }>;
|
|
150
|
+
}
|
|
147
151
|
| undefined;
|
|
148
152
|
if (userAgentDataApi && userAgentDataApi.getHighEntropyValues) {
|
|
149
153
|
try {
|
|
150
154
|
userAgentData = await userAgentDataApi.getHighEntropyValues([
|
|
151
155
|
'platform',
|
|
152
156
|
'platformVersion',
|
|
157
|
+
'fullVersionList',
|
|
153
158
|
]);
|
|
154
159
|
} catch {
|
|
155
160
|
// Ignore the error
|
|
@@ -158,11 +163,21 @@ export const getClientDetails = async (): Promise<ClientDetails> => {
|
|
|
158
163
|
|
|
159
164
|
const userAgent = new UAParser(navigator.userAgent);
|
|
160
165
|
const { browser, os, device, cpu } = userAgent.getResult();
|
|
166
|
+
// If userAgentData is available, it means we are in a modern Chromium browser,
|
|
167
|
+
// and we can use it to get more accurate browser information.
|
|
168
|
+
// We hook into the fullVersionList to find the browser name and version and
|
|
169
|
+
// eventually detect exotic browsers like Samsung Internet, AVG Secure Browser, etc.
|
|
170
|
+
// who by default they identify themselves as "Chromium" in the user agent string.
|
|
171
|
+
// Eliminates the generic "Chromium" name and "Not)A_Brand" name from the list.
|
|
172
|
+
// https://wicg.github.io/ua-client-hints/#create-arbitrary-brands-section
|
|
173
|
+
const uaBrowser = userAgentData?.fullVersionList?.find(
|
|
174
|
+
(v) => !v.brand.includes('Chromium') && !v.brand.match(/[()\-./:;=?_]/g),
|
|
175
|
+
);
|
|
161
176
|
return {
|
|
162
177
|
sdk: sdkInfo,
|
|
163
178
|
browser: {
|
|
164
|
-
name: browser.name || navigator.userAgent,
|
|
165
|
-
version: browser.version || '',
|
|
179
|
+
name: uaBrowser?.brand || browser.name || navigator.userAgent,
|
|
180
|
+
version: uaBrowser?.version || browser.version || '',
|
|
166
181
|
},
|
|
167
182
|
os: {
|
|
168
183
|
name: userAgentData?.platform || os.name || '',
|
package/src/rtc/signal.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { SfuEvent } from '../gen/video/sfu/event/events';
|
|
2
2
|
import { getLogger } from '../logger';
|
|
3
3
|
import { DispatchableMessage, SfuEventKinds } from './Dispatcher';
|
|
4
|
+
import { Tracer } from '../stats';
|
|
4
5
|
|
|
5
6
|
export const createWebSocketSignalChannel = (opts: {
|
|
6
7
|
endpoint: string;
|
|
7
8
|
onMessage: <K extends SfuEventKinds>(message: DispatchableMessage<K>) => void;
|
|
8
9
|
tag: string;
|
|
10
|
+
tracer: Tracer | undefined;
|
|
9
11
|
}) => {
|
|
10
|
-
const { endpoint, onMessage, tag } = opts;
|
|
12
|
+
const { endpoint, onMessage, tag, tracer } = opts;
|
|
11
13
|
const logger = getLogger(['SfuClientWS', tag]);
|
|
12
14
|
logger('debug', 'Creating signaling WS channel:', endpoint);
|
|
13
15
|
const ws = new WebSocket(endpoint);
|
|
@@ -15,14 +17,17 @@ export const createWebSocketSignalChannel = (opts: {
|
|
|
15
17
|
|
|
16
18
|
ws.addEventListener('error', (e) => {
|
|
17
19
|
logger('error', 'Signaling WS channel error', e);
|
|
20
|
+
tracer?.trace('signal.ws.error', e);
|
|
18
21
|
});
|
|
19
22
|
|
|
20
23
|
ws.addEventListener('close', (e) => {
|
|
21
24
|
logger('info', 'Signaling WS channel is closed', e);
|
|
25
|
+
tracer?.trace('signal.ws.close', e);
|
|
22
26
|
});
|
|
23
27
|
|
|
24
28
|
ws.addEventListener('open', (e) => {
|
|
25
29
|
logger('info', 'Signaling WS channel is open', e);
|
|
30
|
+
tracer?.trace('signal.ws.open', e);
|
|
26
31
|
});
|
|
27
32
|
|
|
28
33
|
ws.addEventListener('message', (e) => {
|
|
@@ -34,11 +39,10 @@ export const createWebSocketSignalChannel = (opts: {
|
|
|
34
39
|
|
|
35
40
|
onMessage(message as DispatchableMessage<SfuEventKinds>);
|
|
36
41
|
} catch (err) {
|
|
37
|
-
|
|
38
|
-
'
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
);
|
|
42
|
+
const message =
|
|
43
|
+
'Failed to decode a message. Check whether the Proto models match.';
|
|
44
|
+
logger('error', message, { event: e, error: err });
|
|
45
|
+
tracer?.trace('signal.ws.message.error', message);
|
|
42
46
|
}
|
|
43
47
|
});
|
|
44
48
|
return ws;
|