在 React/Redux 应用程序中存储 RTCPeerConnection 对象的最佳位置在哪里?

evi*_*ing 2 webrtc reactjs redux

RTCPeerConnection 是一个具有某些方法的对象,这些方法在调用时会改变对象(例如,setLocalDescription、addIceCandidate)。这些方法是根据从 WebRTC 连接的另一端接收到的信号调用的(比如当您收到报价或冰候选时)。

因此,这个对象似乎不太适合在 redux 存储中,因为开发人员最初无法控制突变,并且在 redux reducer 中,您不能只创建 RTCPeerConnection 的副本作为这将消除您之前的 webRTC 会话。

但是,在使用 React 的 WebRTC 应用程序中,可能不同的组件需要访问 RTCPeerConnection 对象(例如,它可能是在应用程序中的顶级组件的挂载上实例化的,但随后在某些 UI 组件中,例如在接受调用的树,您想调用 RTCPeerConnection 上的一个方法来创建对收到的 webRTC 报价的答复。或者可能是深层嵌套的组件需要发起调用)。是否唯一的解决方案是将对象作为道具向下传递到组件树?有没有办法将 redux 与这样的复杂对象一起使用?

更新:考虑下面关于使用中间件处理 socket.io 的答案,让我重新定义我原来的问题:如果我有一个 RTCPeerConnection 对象作为顶级组件中的状态,来构建处理调度调用的中间件是否有意义最终必须以某种方式接收对原始 RTCPeerConnection 的引用以进行方法调用,例如setRemoteDescription

mar*_*son 5

Redux 应用程序中类似“socket”的连接对象(websockets、Firebase 等)的标准位置是在中间件中。应用程序的任何需要告诉套接字做某事的部分都可以分派一个被中间件拦截的动作,中间件可以分派动作来更新状态以响应收到的消息。

在我的Redux 插件目录Middleware - Sockets and Adapters部分,有许多现有的各种套接字的中间件示例。

更新

下面是一个 RTC 中间件可能是什么样子的快速示例。该代码完全未经测试,但这应该说明了这个想法:

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);
        }    
    }
}
Run Code Online (Sandbox Code Playgroud)