intro: Hello all, I’ve been playing with mediasoup for a year or so and thought I would ask my first official question on the forums here. Basically its “how do I server-side consume multiple producers on webrtc datachannel in the browser” but I’ll elaborate below. I’m hoping another member can answer my question so I don’t have to bother the developers too much.
setup:
3 clients – firefox, native js
–1 WebRTCPerConnections (from firefox) to mediasoup server
–1 Datachannel (id: 0) on each WebRTCPeerConnections
== All clients connect with success, “ondatachannel” is fired, and I can send and consume messages
1 server – nodejs
–1 mediasoup instance running 1 worker and 1 router.
I have an event handler for ‘newtransport’ attached to the router.
fyi: ‘transport’ and ‘producer’ are arrays of transports, and producer.id respectively.
router.observer.on("newtransport", (newTransport) => {
console.log("Interconnecting new peer connection");
//Consume existing peer's producers.
producer.forEach( (id, index) => {
var consumerOptions = { dataProducerId: id }
newTransport.consumeData(consumerOptions)
.then( (newConsumer) => { console.log("New peer consuming producer " + id + " " + newConsumer.label) });
});
//Make a producer, so other peers can consume this transport's output
var producerOptions = { sctpStreamParameters: { streamId: 0, ordered: true },
label: "AvatarMovements" }
newTransport.produceData(producerOptions)
.then( (newProducer) => {
producer.push(newProducer.id);
console.log("New transport producing as " + newProducer.id);
//Existing peers consume the new peer's producer
transport.forEach( (peerTransport) => {
var consumerOptions = { dataProducerId: newProducer.id }
peerTransport.consumeData(consumerOptions)
.then( (newConsumer) => {
console.log("Existing peer consuming producer "+ newProducer.id +" from new peer transport", transport, "abocve") })
});
transport.push(newTransport);
//console.log(transport);
})
})
Client1 Signaling
OFFER:
v=0
o=mozilla...THIS_IS_SDPARTA-68.7.0 6715870047767296198 0 IN IP4 0.0.0.0
s=-
t=0 0
a=sendrecv
a=fingerprint:sha-256 CF:C0:2C:DA:89:61:99:D8:61:DA:AC:1E:69:41:5C:12:87:EA:7A:72:91:01:D0:44:C3:BB:70:27:5A:95:C0:26
a=group:BUNDLE 0
a=ice-options:trickle
a=msid-semantic:WMS *
m=application 34762 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 192.168.0.147
a=candidate:0 1 UDP 2122252543 192.168.0.147 34762 typ host
a=candidate:3 1 UDP 2122187007 2600:8800:7900:666:428d:5cff:febc:86c4 44004 typ host
a=candidate:6 1 TCP 2105524479 192.168.0.147 9 typ host tcptype active
a=candidate:7 1 TCP 2105458943 2600:8800:7900:666:428d:5cff:febc:86c4 9 typ host tcptype active
a=sendrecv
a=ice-pwd:a228bde5e877c0b9d44d182340e253bb
a=ice-ufrag:d4b95c6b
a=mid:0
a=setup:actpass
a=sctp-port:5000
a=max-message-size:1073741823
ANSWER:
v=0
o=mediasoup 15 0 IN IP4 168.235.79.45
s=-
t=0 0
a=group:BUNDLE 0
m=application 34762 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 168.235.79.45
a=candidate:udpcandidate 1 UDP 1076558079 168.235.79.45 18337 typ host
a=candidate:tcpcandidate 1 TCP 1076302079 168.235.79.45 40620 typ host
a=ice-ufrag:eshnp327opg48bl8
a=ice-pwd:zlm42of4lid9p8ixkezlfdktmre2ehze
a=ice-lite
a=end-of-candidates
a=fingerprint:sha-1 37:1E:2F:18:8B:93:7E:7A:61:F3:E7:57:85:BB:31:50:FA:40:5F:DF
a=fingerprint:sha-224 D4:08:62:AA:7E:02:13:E4:8E:76:D0:5E:15:5F:5B:86:9E:B8:D8:22:7E:B7:EA:12:61:45:4F:CB
a=fingerprint:sha-256 02:A3:F2:BE:7B:12:9E:9E:79:5F:FE:26:9A:C9:DB:58:38:59:AC:12:81:4B:BE:C2:C3:99:30:18:D0:EE:80:8D
a=fingerprint:sha-384 96:E5:19:72:AD:3E:9C:F3:D9:40:A6:92:AE:2B:E9:E8:FB:92:06:2D:FE:B8:DB:61:DB:A4:74:13:EF:04:79:64:74:E7:14:D9:99:1D:6E:A7:5B:B3:E3:CD:15:C6:50:EA
a=fingerprint:sha-512 BF:9D:DA:55:76:8C:01:DB:8C:D6:DB:CD:0A:49:5D:D4:23:93:97:BA:E5:08:2E:92:9F:E1:41:75:85:4C:42:93:08:0E:40:B1:65:F2:6B:45:CF:E2:3D:28:DA:92:CC:52:44:84:73:65:60:40:E5:47:3C:65:A2:13:70:7A:7B:C5
a=setup:active
a=mid:0
a=sctpmap:5000 webrtc-datachannel 262144
Client2 Signaling
OFFER:
v=0
o=mozilla...THIS_IS_SDPARTA-68.7.0 6737140054204525907 0 IN IP4 0.0.0.0
s=-
t=0 0
a=sendrecv
a=fingerprint:sha-256 2A:64:35:B7:33:86:BF:A8:D8:FF:D0:14:05:1B:AA:C6:11:9B:65:C2:EC:07:3F:CD:B3:D1:2C:13:04:37:B5:EE
a=group:BUNDLE 0
a=ice-options:trickle
a=msid-semantic:WMS *
m=application 60140 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 68.0.149.127
a=candidate:0 1 UDP 2122252543 192.168.0.147 60140 typ host
a=candidate:3 1 UDP 2122187007 2600:8800:7900:666:428d:5cff:febc:86c4 47781 typ host
a=candidate:6 1 TCP 2105524479 192.168.0.147 9 typ host tcptype active
a=candidate:7 1 TCP 2105458943 2600:8800:7900:666:428d:5cff:febc:86c4 9 typ host tcptype active
a=candidate:1 1 UDP 1686052863 68.0.149.127 60140 typ srflx raddr 192.168.0.147 rport 60140
a=sendrecv
a=ice-pwd:8cb01e0f82513c79c7a3f719f66bef04
a=ice-ufrag:87eb786f
a=mid:0
a=setup:actpass
a=sctp-port:5000
a=max-message-size:1073741823
ANSWER:
v=0
o=AvatarChat 4 0 IN IP4 168.235.79.45
s=-
t=0 0
a=group:BUNDLE 0
m=application 60140 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 168.235.79.45
a=candidate:udpcandidate 1 UDP 1076558079 168.235.79.45 44352 typ host
a=candidate:tcpcandidate 1 TCP 1076302079 168.235.79.45 55470 typ host
a=ice-ufrag:8h6be6aljaxvo6wu
a=ice-pwd:li3g3zva0v6k935v6nk9sk0fp8fhekeo
a=ice-lite
a=end-of-candidates
a=fingerprint:sha-1 37:1E:2F:18:8B:93:7E:7A:61:F3:E7:57:85:BB:31:50:FA:40:5F:DF
a=fingerprint:sha-224 D4:08:62:AA:7E:02:13:E4:8E:76:D0:5E:15:5F:5B:86:9E:B8:D8:22:7E:B7:EA:12:61:45:4F:CB
a=fingerprint:sha-256 02:A3:F2:BE:7B:12:9E:9E:79:5F:FE:26:9A:C9:DB:58:38:59:AC:12:81:4B:BE:C2:C3:99:30:18:D0:EE:80:8D
a=fingerprint:sha-384 96:E5:19:72:AD:3E:9C:F3:D9:40:A6:92:AE:2B:E9:E8:FB:92:06:2D:FE:B8:DB:61:DB:A4:74:13:EF:04:79:64:74:E7:14:D9:99:1D:6E:A7:5B:B3:E3:CD:15:C6:50:EA
a=fingerprint:sha-512 BF:9D:DA:55:76:8C:01:DB:8C:D6:DB:CD:0A:49:5D:D4:23:93:97:BA:E5:08:2E:92:9F:E1:41:75:85:4C:42:93:08:0E:40:B1:65:F2:6B:45:CF:E2:3D:28:DA:92:CC:52:44:84:73:65:60:40:E5:47:3C:65:A2:13:70:7A:7B:C5
a=setup:active
a=mid:0
a=sctpmap:5000 webrtc-datachannel 262144
Client 3 Signaling:
v=0
o=mozilla...THIS_IS_SDPARTA-68.7.0 8822641039952135555 0 IN IP4 0.0.0.0
s=-
t=0 0
a=sendrecv
a=fingerprint:sha-256 D4:4E:16:B4:46:41:6C:62:8F:56:7A:A7:79:DA:24:43:81:4C:5D:60:59:D9:45:0C:BC:70:72:78:E9:5C:81:24
a=group:BUNDLE 0
a=ice-options:trickle
a=msid-semantic:WMS *
m=application 53492 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 68.0.149.127
a=candidate:0 1 UDP 2122252543 192.168.0.147 53492 typ host
a=candidate:3 1 UDP 2122187007 2600:8800:7900:666:428d:5cff:febc:86c4 35260 typ host
a=candidate:6 1 TCP 2105524479 192.168.0.147 9 typ host tcptype active
a=candidate:7 1 TCP 2105458943 2600:8800:7900:666:428d:5cff:febc:86c4 9 typ host tcptype active
a=candidate:1 1 UDP 1686052863 68.0.149.127 53492 typ srflx raddr 192.168.0.147 rport 53492
a=sendrecv
a=ice-pwd:7440d4cb78ffebc44f70b0fe26f28349
a=ice-ufrag:2997f756
a=mid:0
a=setup:actpass
a=sctp-port:5000
a=max-message-size:1073741823
ANSWER:
v=0
o=AvatarChat 11 0 IN IP4 168.235.79.45
s=-
t=0 0
a=group:BUNDLE 0
m=application 53492 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 168.235.79.45
a=candidate:udpcandidate 1 UDP 1076558079 168.235.79.45 31360 typ host
a=candidate:tcpcandidate 1 TCP 1076302079 168.235.79.45 41295 typ host
a=ice-ufrag:kvaktjdrqjc1o047
a=ice-pwd:d8fpu0683cdep1d4ed46vlbx41ibeyy5
a=ice-lite
a=end-of-candidates
a=fingerprint:sha-1 37:1E:2F:18:8B:93:7E:7A:61:F3:E7:57:85:BB:31:50:FA:40:5F:DF
a=fingerprint:sha-224 D4:08:62:AA:7E:02:13:E4:8E:76:D0:5E:15:5F:5B:86:9E:B8:D8:22:7E:B7:EA:12:61:45:4F:CB
a=fingerprint:sha-256 02:A3:F2:BE:7B:12:9E:9E:79:5F:FE:26:9A:C9:DB:58:38:59:AC:12:81:4B:BE:C2:C3:99:30:18:D0:EE:80:8D
a=fingerprint:sha-384 96:E5:19:72:AD:3E:9C:F3:D9:40:A6:92:AE:2B:E9:E8:FB:92:06:2D:FE:B8:DB:61:DB:A4:74:13:EF:04:79:64:74:E7:14:D9:99:1D:6E:A7:5B:B3:E3:CD:15:C6:50:EA
a=fingerprint:sha-512 BF:9D:DA:55:76:8C:01:DB:8C:D6:DB:CD:0A:49:5D:D4:23:93:97:BA:E5:08:2E:92:9F:E1:41:75:85:4C:42:93:08:0E:40:B1:65:F2:6B:45:CF:E2:3D:28:DA:92:CC:52:44:84:73:65:60:40:E5:47:3C:65:A2:13:70:7A:7B:C5
a=setup:active
a=mid:0
a=sctpmap:5000 webrtc-datachannel 262144
My thoughts in english are: 'for every new transport that connects, make a new producer on the router. Each existing transport should consume this new producer. This new transport should consume all existing producers." - to me, this sounds like a “conference room” setup, but with datachannels.
Expected behavior:
As each new peer connects, they are ‘added’ to the room of interconnected producers&consumers
Actual behavior:
Two peers communicate correctly, but the third peer added only receives data from the first peer. No peers receive data from the third peer.
Interpretation:
Whew, this has been giving me a headache for a few days… The connections to the mediasoup client are correct in that they establish a connection. It could be my SDP conversions to ORTC which I am doing manually but believe I have the understanding to relay one stream for the datachannel. I’m passing the m=application string back to the client, with 5000 as the ‘cosmetic’ port number. I see in the client and libmediasoup libraries there are restrictions based on design about one-way data pipes. but I’m not using either. This is mediasoup nodejs module. I check the transports, and it seems that all the consumers and producers are registered. I have also seen that some streams require to be paused until connected, but the dataproducer has no pause attribute. Also, it may be that there is special magics on local connections that make ice confused.
I feel like it somewhere in the sctp(datachannel sctreamid) muxing getting confused with how I have it setup, or I’m somehow blocking other consumers from consuming…
I have looked at pipeToRouter and such, but it seems that is for transmitting to another router, not what I want.
This behavior might make sense if producers and consumers replaced each other… but I don’t believe thats how it works in mediasoup.
I suppose my real question is: “If it works for two peers on the local network, why does the Nth peer after 2 only get the 1st peers data?”
Any help or nudges in the right direction would be greatly appreciated. I realize that I can use mediasoup client with data channels one way, but am very stubborn and hope to make multiple clients talk over one webrtcdatachannel.
Advice that I am just looking at all ths the wrong way is welcome too, just to be open minded.