Updating Client and curious if we can spoof callbacks?

System was working great till I swapped to latest client, I’d get stuck at _handler:

const { localId: h, rtpParameters: u, rtpSender: m } = await this._handler.send({ track: e, encodings: n, codecOptions: r, codec: s, onRtpSender: p });

I’m curious if it’s acceptable to spoof the callback in such manner and do the handling ourselves.

Transport.on('connect', ({ dtlsParameters }, callback, errback) => {
    if (!Chat.Userlist.Broadcast.get(Chat.Self.handle).connectSent) {
        Chat.Userlist.Broadcast.get(Chat.Self.handle).connectSent = true;

        Chat.WebSocket.send(JSON.stringify({
            "service": "publish",
            "type": "connect",
            "dtlsParameters": dtlsParameters
        }));

        // tell mediasoup the transport is connected
        callback();
    } else {
        callback(); // just in case
    }
});

Transport.on("produce", (producer, callback, errback) => {
    try {
        Chat.WebSocket.send(JSON.stringify({
            "service": "publish",
            "type": producer.kind,
            "rtpParameters": producer.rtpParameters
        }));

        callback({ id: "producer-" + Math.random().toString(36).substr(2, 9) }); 
    } catch (err) {
        errback(err); 
    }
});

Everything connects up fine, I do keep track of the audio/video track produced, I’m just telling mediasoup to connect and spoofing the producerId so we can finalize the request.

This isn’t documented so was wondering if this is acceptable use, I am doing tests to make sure no issues with clearing tracks/etc. Mediasoup-client doesn’t get confused.

Also wanted to point out that browserify didn’t work when bundling the client, it was throwing errors. Switched to webpack and it seemed to work. If this helps at all with the upcoming questions people may have.

Maybe I could revise the documentation to include optional callback for scenarios where you signal in a custom way.

You should not use _handler directly at all. Transport class handles it and runs lot of internal logic on it. If there is some specific event that you think is missing please describe it. IMHO there is nothing missing if you use the public API.

I am not using it directly, I am using transports properly, I’m saying we get stuck at _handler and how our code was before switch mediasoup-client. Our code previously:

Transport.on('connect', ({ dtlsParameters }) => { });

I had to brute force using:
Transport.on('connect', ({ dtlsParameters }, callback, errback) => {});

I just wanted to be sure brute forcing like this was safe.

I’m also not touching the mediasoup client, my main app follows API but some custom signaling logic that makes client await response it may never get (thus stuck at handler). It gets the response just not how your client intends so a callback has to be pushed to force the handler to move along.

No idea why it gets stuck. Enable full debugs with “debug” session storage key set to “*” and check the logs.

I’ve updated from version 3.6.12 to 3.15.6.

Below is what happens when there’s no callback.

and below is when we do callback to satisfy things.

Not sure what changed but my room.js code now has to yell at mediasoup-client.js that the request was good with a callback() or the client sits waiting for it. I just know I tracked it back to this code before realizing I have to satisfy what it wants. Had me derping for a good minute.

I think you guys switched from fire and forget style signaling to request/response contract between client and your app signaling. Doesn’t seem like a bug or glitch, it’s just not documented and now required for my room.js to run the client properly.

This is not true. We haven’t changed anything related to the library usage and it’s exposed API. We have updated mediasoup-client in the mediasoup-demo app without making any change to the demo app and the same at work.

Check if your app is receiving the “connect” event in the sendTransport.

Yes, when I call .produce() atleast once, a connect event is called for the Transport.

//Room.js code (not mediasoup-client)
Transport.on('connect', ({ dtlsParameters }, callback, errback) => {
    /*This will fire when we call produce at least once. No issues with this event being called.*/
    const broadcast = Chat.Userlist.Broadcast.get(Chat.Self.handle);
    if (!broadcast.connectSent) {
        broadcast.connectSent = true;
        Chat.WebSocket.send(JSON.stringify({
            "stumble": "publish",
            "type": "connect",
            "dtlsParameters": dtlsParameters
        }));
    }
    callback(); // This tells the handler to move on to next step which is send the tracks video/audio
});

However the this._handler.send() is waiting on ‘connect’ to fire the callback above or nothing happens. Produce() function won’t complete nor will “produce” event fire till it’s done.

The only thing I know I did different this time was use WebPack (browserify didn’t support latest ES modules or something). That and obviously the versions. So curious if this is a new way to handle the client. Documentation doesn’t speak on event listeners needing callbacks so seemed odd something to bring up.

Doesn’t seem like a bug or glitch or broken, just noticed it.

What do you mean? Docs clearly say that “connect” event is fired with a callback that the app must invoke.

My guess is that callback() is not being called in your event listener. Try adding a console.log after the line in which you invoke callback(). Probably it won’t log.

I’m an idiot man, I was referencing my offline documentation incase things changed I could maintain safely. I didn’t realize this was a change, my dumb ass is looking at the new documentation now… I wish I knew that before I invested an hour debugging your code. LMFAO

transport.on("connect", ({ dtlsParameters }) => {
  // I was doing this for the longest time, no problems. so that was the confusion and didn't realize it was changed.
});

Okay well appreciate you not roasting me to bad.

Could I finish with my initial worry here which was with the produce event, when we callback the producerId. Does this ID need to match in any way or can we just generate a random one?

It must be the server side producerId unless you want to have a map of real and invented producerId values no idea what for

1 Like

So for the client side it wouldn’t matter if it was an invented Id as long (client knows) as the server side has the real Id mapped to a user/handle or some identifier that can be referenced? Just want to be clear.

The setup is a bit odd, but got this way scaling it so trying to play safe. We do map and reference all real producer Ids server-side for easy routing/managing across servers.

That’s right

1 Like

Thank you. I appreciate you and the team a lot.