send transport's dtlsState is connected, but recv remains connecting

I’m using mediasoup v2.
the send transport seems fine, but somehow recv couldn’t get to CheckRemoteFingerprint() and getNegotiatedSrtpProfile().
any solutions?


this is the stats of my succeeded dtls connection of the send transport, which is excatly the same as recv transport’s except it’s dtls connected instead of being stuck in connecting.

DTLS connected means both client and server have made a proper exchange and are transmitting.
Now at this state, this does not mean audio or video is produced/consumed but “could be?”.

So any issues I would check the code and routing of your audio/video devices and/or your handling of creating streams.

Now to add, you got policies like Auto-Play that require you to click the page first before anything can auto-play. If you don’t interact with the page when these elements load up, they’ll stay stuck loading on client side. Definitely consider this one if you made a custom application it tricks many folks.

video element is created when there’re existing peers in the room. With stream added to its srcObject, it loads forever.
The client connects to the server after having clicked one button.
I’ve tried clicking on the page, including button elements, input elements, etc. after the video element shows up,didn’t work.
the front-end transport creating is handled in the room’s “request” callback and the back-end simply let’s the target receive it and returns the result, nothing could go wrong in this part. I’ve also set up the consumers with created send transport when peers are detected.
Did I miss something?

Interaction should occur before videos are told to play. But as mentioned DTLS connected doesn’t mean you’re sending tracks through. You can confirm through webrtc-internals whether or not you are seeing tracks and narrow it down to client handling. :slight_smile:

I checked the internals and here’s what I saw:
with only one peer in the room, two ICE connections were created, the first one managed to connect and began sending the stream, the second one is stuck in “new” state.Checking my wifi, the upload was around 128KB/s.
with two peers in a room(on different devices), according to the stats of the last one joining the room, two connected(local&remote), one stuck in “new”. And the upload rises to around 300KB/s.
I’m sure tracks were being sent to the server, maybe it was the one which didn’t connect, any possible answers?

both successfull ICE connections were between the same public IP and my server on different ports btw.

I’d truthfully question how you route the connecting details for transports for both client/server, would seem obvious you have an issue there if you can connect the first transport for each peer and not their following.

“createTransport”,“enableConsumer”,“createProducer”, any target:“peer” requests.
should all these methods be received by the corresponding peer of client-side? like your requests are handled by your own server-side instance?
that was what my server has been doing, according to the document.

Can you mention the exact steps one by one you do when you try to consume a stream?

using React and Immerjs
the client-side room instance’s join function returns a promise of an array of peers
when the peers come in, I iterate them,
create a mediastream in each loop like this:

const updateStreams = async () => {
const sarr = ;
for (const p of st.peers) {
const stream = new MediaStream();
const promises = => c.receive(st.recv));
const tracks = await Promise.all(promises);
console.log(peer ${}'s tracks:${ =>});
for (const t of tracks) {
setSt((draft) => {
draft.streams = sarr;

then goes the callback:
useEffect(() => {
console.log(“show them”);
for (const s of st.streams) {
const v = otherList.current.querySelector(video[sid="${}"]);
console.log(v, s);
v.srcObject = s;
}, [st.streams]);

tracks are found and added to the stream exactly the way they should be, but the streams won’t effectively load up.

Promise.all might be doing something wrong here. Instead of promise.all do listen for promise for each trach inside loop using then catch, that way you will get to know about errors as well.

Kindly console the things like promises and const tracks to get the idea.

I’m sure it was fine, no errors popped.

Can you confirm of track’s enabled is true and muted is false?

Also check in webrtc-internals whether the peer connection for this track is in connected state and also check the stats graph of this track from there as well to see the bits received per seconds.

Kindly share the screenshots here.

Also make sure to call play() method of video tag after setting stream.

as you can partially see in the screenshot above, the printed track in the array is enabled.
I am sending video without audio so muted or not shouldn’t be a problem
the stats graph of the receiving track was flat 0 cuz its was never trully connected due to the dtls.

this screenshot is of the remote connection, too. I don’t know where the spikes came from.

and this is my local sender, seems working normally

this is a third unknown connection, I don’t know why it is stuck in “new” state. must be the key to my problem.

Also show the screenshots of the both sender and receiver peers from webrtc-internals, not the graphs but the part before graphs, need to see connection state and ice state.