diff --git a/package-lock.json b/package-lock.json index 6053f96..e757b04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,9 @@ "version": "2.3.0", "license": "MIT", "dependencies": { - "@peermetrics/webrtc-stats": "5.4.1", + "@peermetrics/webrtc-stats": "5.5.0", "ua-parser-js": "1.0.2", - "wretch": "1.7.7" + "wretch": "1.7.10" }, "devDependencies": { "@babel/core": "^7.13.10", @@ -1536,9 +1536,9 @@ "dev": true }, "node_modules/@peermetrics/webrtc-stats": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@peermetrics/webrtc-stats/-/webrtc-stats-5.4.1.tgz", - "integrity": "sha512-PjnNNg7JMAkZGnl1J0TY4pP2FF9QcaLXLBQhCmM8perpOmbKIPBvoOx8iJKHj1zbOWEmLmlprPOtwWfhYRZCZA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@peermetrics/webrtc-stats/-/webrtc-stats-5.5.0.tgz", + "integrity": "sha512-Yn2V2N3mNF4HMfl/0k1uRahC9t65cd6OV5G7ZlNnJdaEQl5q/JMw6KKr/9HUQoeCzEo7d+uVFd0N5GLWQ6qqMw==", "dependencies": { "uuid": "8.3.2" }, @@ -5704,9 +5704,9 @@ "dev": true }, "node_modules/wretch": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/wretch/-/wretch-1.7.7.tgz", - "integrity": "sha512-+CYMKQ3ulUFVND3eABUfhGWd43sSXE0UNpcLXcRPBCp/8wJR44yhALeXDhUjRyNDIygT77mMzXlJeGE4PS3iBg==" + "version": "1.7.10", + "resolved": "https://registry.npmjs.org/wretch/-/wretch-1.7.10.tgz", + "integrity": "sha512-UgF2o63bZRsz3LoOxaxzAUdFdlIJzVYbCHHhQ+LNMSBD1FeFJn8ADaekopJclHUm6sN8Lhu0DQFGQloliS0Twg==" }, "node_modules/xdg-basedir": { "version": "4.0.0", @@ -6965,9 +6965,9 @@ } }, "@peermetrics/webrtc-stats": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@peermetrics/webrtc-stats/-/webrtc-stats-5.4.1.tgz", - "integrity": "sha512-PjnNNg7JMAkZGnl1J0TY4pP2FF9QcaLXLBQhCmM8perpOmbKIPBvoOx8iJKHj1zbOWEmLmlprPOtwWfhYRZCZA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@peermetrics/webrtc-stats/-/webrtc-stats-5.5.0.tgz", + "integrity": "sha512-Yn2V2N3mNF4HMfl/0k1uRahC9t65cd6OV5G7ZlNnJdaEQl5q/JMw6KKr/9HUQoeCzEo7d+uVFd0N5GLWQ6qqMw==", "requires": { "uuid": "8.3.2" } @@ -10162,9 +10162,9 @@ "dev": true }, "wretch": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/wretch/-/wretch-1.7.7.tgz", - "integrity": "sha512-+CYMKQ3ulUFVND3eABUfhGWd43sSXE0UNpcLXcRPBCp/8wJR44yhALeXDhUjRyNDIygT77mMzXlJeGE4PS3iBg==" + "version": "1.7.10", + "resolved": "https://registry.npmjs.org/wretch/-/wretch-1.7.10.tgz", + "integrity": "sha512-UgF2o63bZRsz3LoOxaxzAUdFdlIJzVYbCHHhQ+LNMSBD1FeFJn8ADaekopJclHUm6sN8Lhu0DQFGQloliS0Twg==" }, "xdg-basedir": { "version": "4.0.0", diff --git a/package.json b/package.json index 97094d5..5e365d9 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,9 @@ "analytics" ], "dependencies": { - "@peermetrics/webrtc-stats": "5.4.1", + "@peermetrics/webrtc-stats": "5.5.0", "ua-parser-js": "1.0.2", - "wretch": "1.7.7" + "wretch": "1.7.10" }, "devDependencies": { "@babel/core": "^7.13.10", diff --git a/src/index.ts b/src/index.ts index 5372707..bcfb23d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -261,18 +261,11 @@ export class PeerMetrics { throw new Error('The stats module is not instantiated yet.') } - // if the user is using an sdk integration, warn him that a call to addConnection is not needed - // if (this.webrtcSDK) { - // console.warn('You\'ve enabled an integration with an WebRTC sdk, a call to addConnection() is not needed anymore.') - // } - if (typeof options !== 'object') { throw new Error('Argument for addConnection() should be an object.') } let {pc, peerId, peerName, isSfu} = options - // make the peerId a string - peerId = String(peerId) if (!pc) { throw new Error('Missing argument pc: RTCPeerConnection.') @@ -282,6 +275,9 @@ export class PeerMetrics { throw new Error('Missing argument peerId.') } + // make the peerId a string + peerId = String(peerId) + // validate the peerName if it exists if (peerName) { if (typeof peerName !== 'string') { @@ -300,49 +296,14 @@ export class PeerMetrics { log('addConnection', options) - let connectionId - try { - // add the peer to webrtcStats now, so we don't miss any events - let statsResponse = await this.webrtcStats.addConnection({peerId, pc}) - connectionId = statsResponse.connectionId + // add the peer to webrtcStats now, so we don't miss any events + let {connectionId} = await this.webrtcStats.addConnection({peerId, pc}) - // make the request to add the peer to DB - let response = await this.apiWrapper.sendConnectionEvent({ - eventName: 'addConnection', - peerId: peerId, - peerName: peerName, - connectionState: pc.connectionState, - isSfu: !!isSfu - }) + // lets not block this function call for this request + this._sendAddConnectionRequest({connectionId, options: {pc, peerId, peerName, isSfu}}) - if (!response) { - throw new Error('There was a problem while adding this connection') - } - - // we'll receive a new peer id, use peersToMonitor to make the connection between them - peersToMonitor[peerId] = { - id: response.peer_id, - connections: [] - } - - monitoredConnections[connectionId] = response.connection_id - peersToMonitor[peerId].connections.push(response.connection_id) - - // all the events that we captured while waiting for 'addConnection' are here - // send them to the server - eventQueue.map((event) => { - this._handleTimelineEvent(event) - }) - // clear the queue - eventQueue.length = 0 - - return { - connectionId: monitoredConnections[connectionId] - } - } catch (e) { - log(e) - this.webrtcStats.removeConnection({connectionId}) - throw e + return { + connectionId } } @@ -350,45 +311,35 @@ export class PeerMetrics { * Stop listening for events for a specific connection */ async removeConnection (options: RemoveConnectionOptions) { - let {peerId, connectionId, pc} = options - - if (!peerId && !pc && !connectionId) { - throw new Error('Missing arguments. You need to either send a peerId and pc, or a connectionId.') - } - - if ((peerId && !pc) || (pc && !peerId)) { - throw new Error('By not sending a connectionId, you need to send a peerId and a pc (RTCPeerConnection instance)') - } + let peerId, peer - // if we've received a connectionId, we need to find the internal one - // we're using with WebrtcStats - if (connectionId) { - const internalConnectionId = Object.keys(monitoredConnections).find((key) => monitoredConnections[key] === connectionId) + // remove the event listeners + let {connectionId} = this.webrtcStats.removeConnection(options) - if (!internalConnectionId) { - throw new Error(`Could not find a connection with this id ${connectionId}`) - } + const internalId = monitoredConnections[connectionId] - // rewrite options with the new connectionId - options = {connectionId: internalConnectionId} + if (!internalId) { + return } - let {connectionId: internalId} = this.webrtcStats.removeConnection(options) - if (peerId) { - connectionId = Object.keys(monitoredConnections).find((key) => monitoredConnections[key] === internalId) - } else if (connectionId) { - peerId = Object.values(peersToMonitor).find((peer) => peer.connections.includes(connectionId)).id + for (let pId in peersToMonitor) { + if (peersToMonitor[pId].connections.includes(internalId)) { + peer = peersToMonitor[pId] + peerId = pId + break + } } // we need both connectionId and peerId for this request await this.apiWrapper.sendConnectionEvent({ eventName: 'removeConnection', - connectionId, + connectionId: internalId, peerId: peerId }) // cleanup delete monitoredConnections[connectionId] + peer.connections = peer.connections.filter(cId => cId !== internalId) } /** @@ -588,6 +539,52 @@ export class PeerMetrics { .on('timeline', this._handleTimelineEvent.bind(this)) } + /** + * Make a request to the api server to signal a new connection + * @param {String} connectionId The ID of the connection offered by WebRTCStats + */ + private async _sendAddConnectionRequest ({connectionId, options}) { + let {pc, peerId, peerName, isSfu} = options + let response + + try { + // make the request to add the peer to DB + response = await this.apiWrapper.sendConnectionEvent({ + eventName: 'addConnection', + peerId: peerId, + peerName: peerName, + connectionState: pc.connectionState, + isSfu: !!isSfu + }) + + if (!response) { + throw new Error('There was a problem while adding this connection') + } + } catch (e) { + log(e) + this.removeConnection({connectionId}) + throw e + } + + // we'll receive a new peer id, use peersToMonitor to make the connection between them + peersToMonitor[peerId] = { + id: response.peer_id, + connections: [] + } + + monitoredConnections[connectionId] = response.connection_id + peersToMonitor[peerId].connections.push(response.connection_id) + + // all the events that we captured while waiting for 'addConnection' are here + // send them to the server + eventQueue.map((event) => { + this._handleTimelineEvent(event) + }) + + // clear the queue + eventQueue.length = 0 + } + private _handleTimelineEvent (ev) { if (ev.peerId) { if (peersToMonitor[ev.peerId]) {