mediasoup 3.24.0 → 3.24.1

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 CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ### NEXT
4
4
 
5
+ ### 3.24.1
6
+
7
+ - Worker: Don't check `ignoredSubchannel` in piped `DataConsumers` ([PR #1879](https://github.com/versatica/mediasoup/pull/1879)).
8
+
5
9
  ### 3.24.0
6
10
 
7
11
  - `DataProducer.send()`: Add `ignoredSubchannel` optional argument ([PR #1877](https://github.com/versatica/mediasoup/pull/1877)).
@@ -967,8 +967,8 @@ test('transport.consumeData() for a pipe DataProducer succeeds with subchannels'
967
967
  /* ppid */ undefined,
968
968
  /* subchannels */ [125],
969
969
  /* requiredSubchannel */ 666);
970
- // The `pipeDataConsumer` is subscribed to subchannel 666 so it must not
971
- // allow the message to pass through.
970
+ // The final `directDataConsumer` is subscribed to subchannel 666 so it must
971
+ // not receive the message.
972
972
  directDataProducer.send('hello5',
973
973
  /* ppid */ undefined,
974
974
  /* subchannels */ [123],
@@ -979,7 +979,7 @@ test('transport.consumeData() for a pipe DataProducer succeeds with subchannels'
979
979
  directDataProducer.send('hello6',
980
980
  /* ppid */ undefined,
981
981
  /* subchannels */ undefined,
982
- /* requiredSubchannel */ undefined,
982
+ /* requiredSubchannel */ 123,
983
983
  /* ignoredSubchannel */ 777);
984
984
  // Send a message without subchannels so it's guaranteed that it will reach
985
985
  // the final `directDataConsumer`. And wait for reception of this message so
@@ -997,6 +997,63 @@ test('transport.consumeData() for a pipe DataProducer succeeds with subchannels'
997
997
  });
998
998
  expect(receivedMessages).toStrictEqual(['hello1', 'hello2', 'bye']);
999
999
  }, 2000);
1000
+ test('transport.consumeData() for a pipe DataProducer succeeds with ignoredSubchannel', async () => {
1001
+ const directTransport1 = await ctx.router1.createDirectTransport();
1002
+ const directDataProducer = await directTransport1.produceData({
1003
+ label: 'foo',
1004
+ protocol: 'bar',
1005
+ });
1006
+ const { pipeDataConsumer } = await ctx.router1.pipeToRouter({
1007
+ dataProducerId: directDataProducer.id,
1008
+ router: ctx.router2,
1009
+ });
1010
+ const directTransport2 = await ctx.router2.createDirectTransport();
1011
+ const directDataConsumer1 = await directTransport2.consumeData({
1012
+ dataProducerId: directDataProducer.id,
1013
+ subchannels: [111],
1014
+ });
1015
+ const directDataConsumer2 = await directTransport2.consumeData({
1016
+ dataProducerId: directDataProducer.id,
1017
+ subchannels: [222],
1018
+ });
1019
+ // A pipe DataConsumer must be subscribed to the union of the subchannels of
1020
+ // all the DataConsumers behind it.
1021
+ await pipeDataConsumer.setSubchannels([111, 222]);
1022
+ const receivedMessages1 = [];
1023
+ const receivedMessages2 = [];
1024
+ // Resolved once both final DataConsumers have received the last sent message.
1025
+ const allReceived = Promise.all([
1026
+ [directDataConsumer1, receivedMessages1],
1027
+ [directDataConsumer2, receivedMessages2],
1028
+ ].map(([dataConsumer, receivedMessages]) => new Promise(resolve => {
1029
+ dataConsumer.on('message', message => {
1030
+ const receivedMessage = message.toString('utf8');
1031
+ receivedMessages.push(receivedMessage);
1032
+ // Resolve once the last sent message is received.
1033
+ if (receivedMessage === 'bye') {
1034
+ resolve();
1035
+ }
1036
+ });
1037
+ })));
1038
+ // The `pipeDataConsumer` is subscribed to subchannel 111, but being a pipe
1039
+ // DataConsumer it must not apply `ignoredSubchannel` itself. Otherwise it
1040
+ // would drop the message for every DataConsumer behind it rather than just
1041
+ // for `directDataConsumer1`. `ignoredSubchannel` travels within the message
1042
+ // and is applied by the final DataConsumers, so `directDataConsumer2` must
1043
+ // still receive it.
1044
+ directDataProducer.send('hello1',
1045
+ /* ppid */ undefined,
1046
+ /* subchannels */ undefined,
1047
+ /* requiredSubchannel */ undefined,
1048
+ /* ignoredSubchannel */ 111);
1049
+ // Send a message without subchannels so it's guaranteed that it will reach
1050
+ // both final DataConsumers. And wait for reception of this message so at
1051
+ // this time we know whether the previous one reached them.
1052
+ directDataProducer.send('bye');
1053
+ await allReceived;
1054
+ expect(receivedMessages1).toStrictEqual(['bye']);
1055
+ expect(receivedMessages2).toStrictEqual(['hello1', 'bye']);
1056
+ }, 2000);
1000
1057
  test('dataProducer.close() is transmitted to pipe DataConsumer', async () => {
1001
1058
  const { pipeDataProducer } = await ctx.router1.pipeToRouter({
1002
1059
  dataProducerId: ctx.dataProducer.id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mediasoup",
3
- "version": "3.24.0",
3
+ "version": "3.24.1",
4
4
  "description": "Cutting Edge WebRTC Video Conferencing",
5
5
  "contributors": [
6
6
  "Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)",
@@ -129,14 +129,14 @@
129
129
  "globals": "^17.9.0",
130
130
  "ini": "^7.0.0",
131
131
  "jest": "^30.4.2",
132
- "knip": "^6.31.0",
133
- "marked": "^18.0.7",
132
+ "knip": "^6.32.0",
133
+ "marked": "^18.0.9",
134
134
  "open-cli": "^9.0.0",
135
135
  "pick-port": "^2.2.1",
136
136
  "prettier": "^3.9.6",
137
137
  "ts-jest": "^29.4.12",
138
138
  "typescript": "^6.0.3",
139
- "typescript-eslint": "^8.65.0",
139
+ "typescript-eslint": "^8.66.0",
140
140
  "werift-sctp": "^0.0.11"
141
141
  }
142
142
  }
@@ -21,9 +21,9 @@
21
21
  }
22
22
  },
23
23
  "node_modules/brace-expansion": {
24
- "version": "5.0.8",
25
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz",
26
- "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==",
24
+ "version": "5.0.9",
25
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
26
+ "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
27
27
  "license": "MIT",
28
28
  "dependencies": {
29
29
  "balanced-match": "^4.0.2"
@@ -105,9 +105,9 @@
105
105
  "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="
106
106
  },
107
107
  "brace-expansion": {
108
- "version": "5.0.8",
109
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz",
110
- "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==",
108
+ "version": "5.0.9",
109
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
110
+ "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
111
111
  "requires": {
112
112
  "balanced-match": "^4.0.2"
113
113
  }
@@ -502,8 +502,8 @@ namespace RTC
502
502
  return false;
503
503
  }
504
504
 
505
- // Only verify subchannels if this is not a piped DataConsumer or if this is
506
- // a piped DataConsumer and it's subscribed to at least one subchannel.
505
+ // Only verify subchannels if this is not a piped DataConsumer or if this
506
+ // is a piped DataConsumer and it's subscribed to at least one subchannel.
507
507
  const bool verifySubchannels = !this->pipe || !this->subchannels.empty();
508
508
 
509
509
  if (verifySubchannels)
@@ -521,9 +521,14 @@ namespace RTC
521
521
  return false;
522
522
  }
523
523
 
524
- // If an ignored subchannel is given, verify that this data consumer is not
525
- // subscribed to it, otherwise don't send this message to it.
526
- if (ignoredSubchannel.has_value() && this->subchannels.contains(ignoredSubchannel.value()))
524
+ // If an ignored subchannel is given, verify that this data consumer is
525
+ // not subscribed to it, otherwise don't send this message to it.
526
+ // NOTE: We don't check this in piped DataConsumers on purpose. Otherwise
527
+ // a message generated by peer X and forwarded to all peers in another
528
+ // host wouldn't pass this filter in the local PipeTransport.
529
+ if (
530
+ !this->pipe && ignoredSubchannel.has_value() &&
531
+ this->subchannels.contains(ignoredSubchannel.value()))
527
532
  {
528
533
  if (cb)
529
534
  {