From c2d96b81edbea6398f7b1b07261df35e0998423a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Mill=C3=A1n?= Date: Thu, 26 Oct 2023 13:10:33 +0200 Subject: [PATCH 1/6] Node: Add RouterDump and DirectTransportDump types --- node/src/DirectTransport.ts | 4 ++- node/src/Router.ts | 57 +++++++++++++++++++++++++++++++-- node/src/tests/test-Consumer.ts | 14 ++++---- node/src/utils.ts | 48 +++++++++++++++++++++++++-- 4 files changed, 110 insertions(+), 13 deletions(-) diff --git a/node/src/DirectTransport.ts b/node/src/DirectTransport.ts index d5ee0b85fc..99da02ede9 100644 --- a/node/src/DirectTransport.ts +++ b/node/src/DirectTransport.ts @@ -33,6 +33,8 @@ export type DirectTransportOptions /** * Dump Transport. */ - async dump(): Promise + async dump(): Promise { logger.debug('dump()'); diff --git a/node/src/Router.ts b/node/src/Router.ts index 839aa06d0e..886bdf1525 100644 --- a/node/src/Router.ts +++ b/node/src/Router.ts @@ -24,7 +24,7 @@ import { RtpCapabilities, RtpCodecCapability } from './RtpParameters'; import { cryptoSuiteToFbs } from './SrtpParameters'; import { NumSctpStreams } from './SctpParameters'; import { AppData, Either } from './types'; -import { generateUUIDv4 } from './utils'; +import { generateUUIDv4, parseVector, parseStringStringVector, parseStringStringArrayVector } from './utils'; import * as FbsActiveSpeakerObserver from './fbs/active-speaker-observer'; import * as FbsAudioLevelObserver from './fbs/audio-level-observer'; import * as FbsRequest from './fbs/request'; @@ -128,6 +128,41 @@ export type PipeToRouterResult = pipeDataProducer?: DataProducer; }; +export type RouterDump = { + /** + * The Router id. + */ + id: string; + /** + * Id of Transports. + */ + transportIds: string[]; + /** + * Id of RtpObservers. + */ + rtpObserverIds: string[]; + /** + * Array of Producer id and its respective Consumer ids. + */ + mapProducerIdConsumerIds: { key: string; values: string[] }[]; + /** + * Array of Consumer id and its Producer id. + */ + mapConsumerIdProducerId: {key: string; value: string}[]; + /** + * Array of Producer id and its respective Observer ids. + */ + mapProducerIdObserverIds: {key: string; values: string[]}[]; + /** + * Array of Producer id and its respective DataConsumer ids. + */ + mapDataProducerIdDataConsumerIds: {key: string; values: string[]}[]; + /** + * Array of DataConsumer id and its DataProducer id. + */ + mapDataConsumerIdDataProducerId: {key: string; value: string}[]; +}; + type PipeTransportPair = { [key: string]: PipeTransport; @@ -376,7 +411,7 @@ export class Router /** * Dump Router. */ - async dump(): Promise + async dump(): Promise { logger.debug('dump()'); @@ -393,7 +428,7 @@ export class Router response.body(dump); - return dump.unpack(); + return parseRouterDumpResponse(dump); } /** @@ -1566,3 +1601,19 @@ export class Router } } } + +export function parseRouterDumpResponse( + binary: FbsRouter.DumpResponse +): RouterDump +{ + return { + id : binary.id()!, + transportIds : parseVector(binary, 'transportIds'), + rtpObserverIds : parseVector(binary, 'rtpObserverIds'), + mapProducerIdConsumerIds : parseStringStringArrayVector(binary, 'mapProducerIdConsumerIds'), + mapConsumerIdProducerId : parseStringStringVector(binary, 'mapConsumerIdProducerId'), + mapProducerIdObserverIds : parseStringStringArrayVector(binary, 'mapProducerIdObserverIds'), + mapDataProducerIdDataConsumerIds : parseStringStringArrayVector(binary, 'mapDataProducerIdDataConsumerIds'), + mapDataConsumerIdDataProducerId : parseStringStringVector(binary, 'mapDataConsumerIdDataProducerId') + }; +} diff --git a/node/src/tests/test-Consumer.ts b/node/src/tests/test-Consumer.ts index 642db30836..e006bd7caf 100644 --- a/node/src/tests/test-Consumer.ts +++ b/node/src/tests/test-Consumer.ts @@ -1009,27 +1009,27 @@ test('consumer.close() succeeds', async () => expect(onObserverClose).toHaveBeenCalledTimes(1); expect(audioConsumer.closed).toBe(true); - let dump = await router.dump(); + const routerDump = await router.dump(); - expect(dump.mapProducerIdConsumerIds) + expect(routerDump.mapProducerIdConsumerIds) .toEqual(expect.arrayContaining([ { key: audioProducer.id, values: [ ] } ])); - expect(dump.mapConsumerIdProducerId) + expect(routerDump.mapConsumerIdProducerId) .toEqual(expect.arrayContaining([ { key: videoConsumer.id, value: videoProducer.id } ])); - expect(dump.mapConsumerIdProducerId) + expect(routerDump.mapConsumerIdProducerId) .toEqual(expect.arrayContaining([ { key: videoPipeConsumer.id, value: videoProducer.id } ])); - dump = await transport2.dump(); + const transportDump = await transport2.dump(); - dump.consumerIds = dump.consumerIds.sort(); + transportDump.consumerIds = transportDump.consumerIds.sort(); - expect(dump) + expect(routerDump) .toMatchObject( { id : transport2.id, diff --git a/node/src/utils.ts b/node/src/utils.ts index 72c736e03d..07c4e06f2e 100644 --- a/node/src/utils.ts +++ b/node/src/utils.ts @@ -91,6 +91,25 @@ export function parseVector( return array; } +/** + * Parse flatbuffers vector of StringString into the corresponding array. + */ +export function parseStringStringVector( + binary: any, methodName: string +): { key: string; value: string }[] +{ + const array: { key: string; value: string }[] = []; + + for (let i=0; i Date: Thu, 26 Oct 2023 15:08:28 +0200 Subject: [PATCH 2/6] eslint: set 'space-infix-ops' rule --- node/.eslintrc.js | 1 + node/src/RtpParameters.ts | 6 +++--- node/src/WebRtcTransport.ts | 4 ++-- node/src/ortc.ts | 2 +- node/src/utils.ts | 14 +++++++------- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/node/.eslintrc.js b/node/.eslintrc.js index 61a42372e6..e541c5acd6 100644 --- a/node/.eslintrc.js +++ b/node/.eslintrc.js @@ -183,6 +183,7 @@ const eslintConfig = } ], 'space-in-parens' : [ 2, 'never' ], + 'space-infix-ops' : [ 2, { 'int32Hint': false } ], 'spaced-comment' : [ 2, 'always' ], 'strict' : 2, 'valid-typeof' : 2, diff --git a/node/src/RtpParameters.ts b/node/src/RtpParameters.ts index 532fb014b2..760aaa15c8 100644 --- a/node/src/RtpParameters.ts +++ b/node/src/RtpParameters.ts @@ -396,7 +396,7 @@ export function serializeRtpParameters( const rtcpFeedback: number[] = []; - for (const rtcp of codec.rtcpFeedback?? []) + for (const rtcp of codec.rtcpFeedback ?? []) { const typeOffset = builder.createString(rtcp.type); const rtcpParametersOffset = builder.createString(rtcp.parameter); @@ -575,7 +575,7 @@ export function serializeParameters( if (typeof value === 'boolean') { parameterOffset = FbsParameter.createParameter( - builder, keyOffset, FbsValue.Boolean, value === true ? 1:0 + builder, keyOffset, FbsValue.Boolean, value === true ? 1 : 0 ); } else if (typeof value === 'number') @@ -638,7 +638,7 @@ export function parseParameters(data: any): any { const parameters: any = {}; - for (let i=0; i= 0; --idx) + for (let idx = consumerParams.codecs.length - 1; idx >= 0; --idx) { const codec = consumerParams.codecs[idx]; diff --git a/node/src/utils.ts b/node/src/utils.ts index 07c4e06f2e..6f9ad900d2 100644 --- a/node/src/utils.ts +++ b/node/src/utils.ts @@ -76,7 +76,7 @@ export function parseVector( { const array: Type[] = []; - for (let i=0; i Date: Thu, 26 Oct 2023 15:15:40 +0200 Subject: [PATCH 3/6] fix curly brace --- node/src/Router.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/node/src/Router.ts b/node/src/Router.ts index 886bdf1525..edecf0ce4b 100644 --- a/node/src/Router.ts +++ b/node/src/Router.ts @@ -128,7 +128,8 @@ export type PipeToRouterResult = pipeDataProducer?: DataProducer; }; -export type RouterDump = { +export type RouterDump = +{ /** * The Router id. */ From 2888abe38be06a47d30fff6277891bb50f4fb46b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Mill=C3=A1n?= Date: Thu, 26 Oct 2023 15:25:32 +0200 Subject: [PATCH 4/6] Node: Add WorkerDump type --- node/src/Worker.ts | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/node/src/Worker.ts b/node/src/Worker.ts index 3c8ff24edb..5e4f5f7805 100644 --- a/node/src/Worker.ts +++ b/node/src/Worker.ts @@ -8,7 +8,7 @@ import { Channel } from './Channel'; import { Router, RouterOptions } from './Router'; import { WebRtcServer, WebRtcServerOptions } from './WebRtcServer'; import { AppData } from './types'; -import { generateUUIDv4 } from './utils'; +import { generateUUIDv4, parseVector } from './utils'; import { Event } from './fbs/notification'; import * as FbsRequest from './fbs/request'; import * as FbsWorker from './fbs/worker'; @@ -184,7 +184,7 @@ export type WorkerResourceUsage = export type WorkerDump = { pid : number; - webrtcServerIds : string[]; + webRtcServerIds : string[]; routerIds : string[]; channelMessageHandlers : { @@ -581,7 +581,7 @@ export class Worker /** * Dump Worker. */ - async dump(): Promise + async dump(): Promise { logger.debug('dump()'); @@ -595,7 +595,7 @@ export class Worker response.body(dump); - return dump.unpack(); + return parseWorkerDumpResponse(dump); } /** @@ -807,3 +807,19 @@ export class Worker this.#observer.safeEmit('close'); } } + +export function parseWorkerDumpResponse( + binary: FbsWorker.DumpResponse +): WorkerDump +{ + return { + pid : binary.pid()!, + webRtcServerIds : parseVector(binary, 'webRtcServerIds'), + routerIds : parseVector(binary, 'routerIds'), + channelMessageHandlers : + { + channelRequestHandlers : parseVector(binary.channelMessageHandlers()!, 'channelRequestHandlers'), + channelNotificationHandlers : parseVector(binary.channelMessageHandlers()!, 'channelNotificationHandlers') + } + }; +} From ae2d9405f94e531015039b347fb9d5f667332b06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Baz=20Castillo?= Date: Thu, 26 Oct 2023 15:43:01 +0200 Subject: [PATCH 5/6] Update node/src/tests/test-Consumer.ts --- node/src/tests/test-Consumer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/src/tests/test-Consumer.ts b/node/src/tests/test-Consumer.ts index e006bd7caf..3723019460 100644 --- a/node/src/tests/test-Consumer.ts +++ b/node/src/tests/test-Consumer.ts @@ -1029,7 +1029,7 @@ test('consumer.close() succeeds', async () => transportDump.consumerIds = transportDump.consumerIds.sort(); - expect(routerDump) + expect(transportDump) .toMatchObject( { id : transport2.id, From 3fe9158881830c388b7b24417211aaa53e5731be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Mill=C3=A1n?= Date: Thu, 26 Oct 2023 16:04:50 +0200 Subject: [PATCH 6/6] Node: Add WebRtcServerDump --- node/src/Transport.ts | 6 +-- node/src/WebRtcServer.ts | 76 +++++++++++++++++++++++++++++-------- worker/fbs/webRtcServer.fbs | 2 +- 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/node/src/Transport.ts b/node/src/Transport.ts index 586a5c600c..eae0cca9a8 100644 --- a/node/src/Transport.ts +++ b/node/src/Transport.ts @@ -599,7 +599,7 @@ export class Transport async dump(): Promise { // Should not happen. - throw new Error('method not implemented in the subclass'); + throw new Error('method implemented in the subclass'); } /** @@ -610,7 +610,7 @@ export class Transport async getStats(): Promise { // Should not happen. - throw new Error('method not implemented in the subclass'); + throw new Error('method implemented in the subclass'); } /** @@ -622,7 +622,7 @@ export class Transport async connect(params: any): Promise { // Should not happen. - throw new Error('method not implemented in the subclass'); + throw new Error('method implemented in the subclass'); } /** diff --git a/node/src/WebRtcServer.ts b/node/src/WebRtcServer.ts index 8e1547a8be..ad45f9e179 100644 --- a/node/src/WebRtcServer.ts +++ b/node/src/WebRtcServer.ts @@ -29,7 +29,7 @@ export type WebRtcServerOptions = export type WebRtcServerListenInfo = TransportListenInfo; export type WebRtcServerEvents = -{ +{ workerclose: []; // Private events. '@close': []; @@ -42,6 +42,34 @@ export type WebRtcServerObserverEvents = webrtctransportunhandled: [WebRtcTransport]; }; +export type WebRtcServerDump = +{ + id: string; + udpSockets: IpPort[]; + tcpServers: IpPort[]; + webRtcTransportIds: string[]; + localIceUsernameFragments: IceUserNameFragment[]; + tupleHashes: TupleHash[]; +}; + +type IpPort = +{ + ip: string; + port: number; +}; + +type IceUserNameFragment = +{ + localIceUsernameFragment: string; + webRtcTransportId: string; +}; + +type TupleHash = +{ + tupleHash: number; + webRtcTransportId: string; +}; + type WebRtcServerInternal = { webRtcServerId: string; @@ -213,7 +241,7 @@ export class WebRtcServer /** * Dump WebRtcServer. */ - async dump(): Promise + async dump(): Promise { logger.debug('dump()'); @@ -248,32 +276,48 @@ export class WebRtcServer } } -// TODO: This function should return WebRtcServerDump TypeScript type but we -// don't have it yet (same for many other dump() methods everywhere). +function parseIpPort(binary: FbsWebRtcServer.IpPort): IpPort +{ + return { + ip : binary.ip()!, + port : binary.port() + }; +} + +function parseIceUserNameFragment(binary: FbsWebRtcServer.IceUserNameFragment): IceUserNameFragment +{ + return { + localIceUsernameFragment : binary.localIceUsernameFragment()!, + webRtcTransportId : binary.webRtcTransportId()! + }; +} + +function parseTupleHash(binary: FbsWebRtcServer.TupleHash): TupleHash +{ + return { + tupleHash : Number(binary.tupleHash()!), + webRtcTransportId : binary.webRtcTransportId()! + }; +} + function parseWebRtcServerDump( data: FbsWebRtcServer.DumpResponse -): any +): WebRtcServerDump { return { - id : data.id(), + id : data.id()!, udpSockets : utils.parseVector( - data, 'udpSockets', (udpSocket: any) => udpSocket.unpack() + data, 'udpSockets', parseIpPort ), tcpServers : utils.parseVector( - data, 'tcpServers', (tcpServer: any) => tcpServer.unpack() + data, 'tcpServers', parseIpPort ), webRtcTransportIds : utils.parseVector(data, 'webRtcTransportIds'), localIceUsernameFragments : utils.parseVector( - data, 'localIceUsernameFragments', (localIceUsernameFragment: any) => localIceUsernameFragment.unpack() + data, 'localIceUsernameFragments', parseIceUserNameFragment ), tupleHashes : utils.parseVector( - data, 'tupleHashes', (tupleHash: any) => - { - return { - localIceUsernameFragment : Number(tupleHash.localIceUsernameFragment()), - webRtcTransportId : tupleHash.webRtcTransportId() - }; - } + data, 'tupleHashes', parseTupleHash ) }; } diff --git a/worker/fbs/webRtcServer.fbs b/worker/fbs/webRtcServer.fbs index 6f93b9bbc6..7d9c4edde1 100644 --- a/worker/fbs/webRtcServer.fbs +++ b/worker/fbs/webRtcServer.fbs @@ -13,7 +13,7 @@ table IceUserNameFragment { } table TupleHash { - local_ice_username_fragment: uint64; + tuple_hash: uint64; web_rtc_transport_id: string (required); }