From 5b1889e77b5118ea577e19708be5ee770248ea52 Mon Sep 17 00:00:00 2001 From: Koushik Dutta Date: Sun, 17 Mar 2024 09:42:38 -0700 Subject: [PATCH] webrtc: add connection timeout --- plugins/webrtc/package-lock.json | 24 +++++++------- plugins/webrtc/src/main.ts | 38 +++++++++++++---------- plugins/webrtc/src/peerconnection-util.ts | 10 ++++-- 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/plugins/webrtc/package-lock.json b/plugins/webrtc/package-lock.json index b7c7e1a429..6622e825aa 100644 --- a/plugins/webrtc/package-lock.json +++ b/plugins/webrtc/package-lock.json @@ -24,12 +24,11 @@ "dependencies": { "@scrypted/sdk": "file:../sdk", "@scrypted/server": "file:../server", - "http-auth-utils": "^3.0.2", - "node-fetch-commonjs": "^3.1.1", + "http-auth-utils": "^5.0.1", "typescript": "^5.3.3" }, "devDependencies": { - "@types/node": "^20.10.8", + "@types/node": "^20.11.0", "ts-node": "^10.9.2" } }, @@ -84,7 +83,7 @@ }, "../../sdk": { "name": "@scrypted/sdk", - "version": "0.3.4", + "version": "0.3.14", "license": "ISC", "dependencies": { "@babel/preset-typescript": "^7.18.6", @@ -143,9 +142,9 @@ "dev": true }, "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==" } }, "dependencies": { @@ -154,9 +153,8 @@ "requires": { "@scrypted/sdk": "file:../sdk", "@scrypted/server": "file:../server", - "@types/node": "^20.10.8", - "http-auth-utils": "^3.0.2", - "node-fetch-commonjs": "^3.1.1", + "@types/node": "^20.11.0", + "http-auth-utils": "^5.0.1", "ts-node": "^10.9.2", "typescript": "^5.3.3" } @@ -201,9 +199,9 @@ "dev": true }, "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==" } } } diff --git a/plugins/webrtc/src/main.ts b/plugins/webrtc/src/main.ts index d1405ed71f..970052ac73 100644 --- a/plugins/webrtc/src/main.ts +++ b/plugins/webrtc/src/main.ts @@ -678,24 +678,11 @@ class WebRTCBridge extends ScryptedDeviceBase implements BufferConverter { this.toMimeType = ScryptedMimeTypes.RTCConnectionManagement; } - async convert(data: any, fromMimeType: string, toMimeType: string, options?: MediaObjectOptions): Promise { + async convertInternal(result: ReturnType, cleanup: Deferred, data: any, fromMimeType: string, toMimeType: string, options?: MediaObjectOptions): Promise { const session = data as RTCSignalingSession; const maximumCompatibilityMode = !!this.plugin.storageSettings.values.maximumCompatibilityMode; const clientOptions = await legacyGetSignalingSessionOptions(session); - const result = zygote(); - - const cleanup = new Deferred(); - - this.plugin.activeConnections++; - result.worker.on('exit', () => { - this.plugin.activeConnections--; - cleanup.resolve('worker exited'); - }); - cleanup.promise.finally(() => { - result.worker.terminate() - }); - const { createConnection } = await result.result; const connection = await createConnection({}, undefined, session, maximumCompatibilityMode, @@ -711,10 +698,29 @@ class WebRTCBridge extends ScryptedDeviceBase implements BufferConverter { await connection.negotiateRTCSignalingSession(); await connection.waitConnected(); - // await connection.negotiateRTCSignalingSession(); - return connection; } + + async convert(data: any, fromMimeType: string, toMimeType: string, options?: MediaObjectOptions): Promise { + const result = zygote(); + this.plugin.activeConnections++; + const cleanup = new Deferred(); + result.worker.on('exit', () => { + this.plugin.activeConnections--; + cleanup.resolve('worker exited'); + }); + cleanup.promise.finally(() => { + result.worker.terminate() + }); + + try { + return await timeoutPromise(2 * 60 * 1000, this.convertInternal(result, cleanup, data, fromMimeType, toMimeType, options)); + } + catch (e) { + cleanup.resolve(e.toString()); + throw e; + } + } } export default WebRTCPlugin; diff --git a/plugins/webrtc/src/peerconnection-util.ts b/plugins/webrtc/src/peerconnection-util.ts index aa934a722e..3b3f58b251 100644 --- a/plugins/webrtc/src/peerconnection-util.ts +++ b/plugins/webrtc/src/peerconnection-util.ts @@ -55,9 +55,13 @@ export function waitIceConnected(pc: RTCPeerConnection) { } export function waitClosed(pc: RTCPeerConnection) { - return statePromise(pc.connectionStateChange, () => { - return isPeerConnectionClosed(pc) || isPeerIceConnectionClosed(pc); - }) + const connectPromise = statePromise(pc.connectionStateChange, () => { + return isPeerConnectionClosed(pc); + }); + const iceConnectPromise = statePromise(pc.iceConnectionStateChange, () => { + return isPeerIceConnectionClosed(pc); + }); + return Promise.any([connectPromise, iceConnectPromise]); } export function logConnectionState(console: Console, pc: RTCPeerConnection) {