In fact, by checking the code I’ve found something that can be improved (and it’s done in v3 branch, still not released in a new version as there are other ongoing changes that must be super tested):
Note however that this won’t fix your problem. I’m trying to figure out if something can be done within mediasoup to allow your usage (simultaneous calls to router1.pipeToRouter({ producerId: producer1.id, router: router2 })
with same values). Definitely it’s not possible. The “problem” is in this part of the pipeToRouter()
method:
pipeConsumer = await localPipeTransport.consume({ producerId });
pipeProducer = await remotePipeTransport.produce(
{
id : producer.id,
kind : pipeConsumer.kind,
rtpParameters : pipeConsumer.rtpParameters,
paused : pipeConsumer.producerPaused,
appData : producer.appData
});
Instead of directly calling localPipeTransport.consume()
we may first try to look for a Consumer that consumer.producerId === producerId
in localPipeTransport
, and do a similar thing in remotePipeTransport
by looking for a Producer that producer.id === producerId
and, if found, return the matching Consumer and Producer instead of calling consume()
and produce()
(that would fail due to duplicated producerId
in remotePipeTransport.produce()
.
However, methods above (consume()
and produce()
) are async so if we call simultaneously to pipeToRouter()
with same values we cannot even anticipate whether the ongoing Consumer and Producer do already exist and reuse them as return value. Yeah, for that we would need to use an “async queue” but that would be to time consuming as you have noticed in your app code.
NOTE: The awaitQueue
I’ve added in the commit above is just for the PipeTransportPair
generation which happens just once between two exact routers
, so it should not be a problem at all.
This is funny because, indeed, calls to getOrCreateRoom()
in the demo server are wrapped/protected by a call to awaitQueue.push()
IMHO you may have to refactor a bit your code so you don’t call twice to pipeToRouter()
with same values. I think the way to go would be a smarter use of awaitQueue
(or other similar modules). You may have an async method in your code:
async waitForPipeStuff(router1, router2, producer) {
await this._awaitQueue.push(() => {
if (this._setProducerRouter.has(`${producer.id}-${router2.id}`)
return;
await router1.pipeToRouter({ producerId: producer.id, router: router2 });
this._setProducerRouter.add(`${producer.id}-${router2.id}`);
});
}
BTW please also take this into account if you are trying to broadcast video to MANY endpoints: