Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is the best place to store an RTCPeerConnection object in a React/Redux app?

RTCPeerConnection is an object with certain methods that when called mutate the object (for example, setLocalDescription, addIceCandidate). These methods get called based on received signaling from the other side of a WebRTC connection (like when you receive an offer, or an ice candidate).

Therefore, this object does not seem well-suited for being in a redux store, since the developer doesn't at a first approximation have control over the mutations, and in a redux reducer you can't just create a copy of an RTCPeerConnection as this would eliminate your previous webRTC session.

However, in a WebRTC app that uses React, perhaps different components need access to the RTCPeerConnection object (for instance, maybe it is instantiated on mount of the top level component in the app, but then in some UI component like a modal deep in the tree that accepts a call, you want to call a method on RTCPeerConnection to create an answer to the webRTC offer that was received. Or maybe a deeply nested component needs to initiate a call). Is it the case that the only solution is to pass the object as props down the component tree? Is there no way to use redux with a complex object like this?

UPDATE: considering the answer below about using middleware for handling socket.io, let me reframe my original question: would it make sense, if I have an RTCPeerConnection object as state in a top-level component, to build middleware that that handles dispatch calls that ultimately must receive some way some how a reference to the original RTCPeerConnection to make a method call such as setRemoteDescription?

like image 986
evianpring Avatar asked Nov 07 '25 21:11

evianpring


1 Answers

The standard place for "socket"-like connection objects (websockets, Firebase, etc) in a Redux app is in a middleware. Any part of the application that needs to tell the socket to do something can dispatch an action that is intercepted by the middleware, and the middleware can dispatch actions to update the state in response to received messages.

There's dozens of existing examples of middleware for various sockets in the Middleware - Sockets and Adapters section of my Redux addons catalog.

update

Here's a quick example of what an RTC middleware might look like. The code is completely untested, but this should illustrate the idea:

function createRtcMiddleware() {
    return (store) => {
        let rtcPeerConnection = null;

        return (next) => action => {
            switch(action.type) {
                case "RTC_CONNECTION_CREATE": {
                    const {rtcConfig} = action;
                    rtcPeerConnection = new RTCPeerConnection(rtcConfig);

                    rtcPeerConnection.somecallback = () => {     
                        // maybe dispatch a Redux action in response to 
                        // a received message                
                    };

                    // Do not pass the action down the pipeline, since only 
                    // this middleware cares about it
                    return;
                }
                case "RTC_CONNECTION_SET_DESCRIPTION": {
                    if(rtcPeerConnection) {
                        rtcPeerConnection.setDescription(action.description);
                    }

                    return;
                }
            }

            // If we don't care about it, pass it down the pipeline
            return next(action);
        }    
    }
}
like image 78
markerikson Avatar answered Nov 11 '25 07:11

markerikson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!