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

时间:2017-07-05 21:45:16

标签: reactjs redux webrtc

RTCPeerConnection是一个具有某些方法的对象,当调用该对象时(例如,setLocalDescription,addIceCandidate)。这些方法基于从WebRTC连接的另一侧接收的信令被调用(例如当您收到要约或冰候选者时)。

因此,这个对象似乎不适合在redux存储中,因为开发人员不会在第一次近似时控制突变,而在redux reducer中你不能只创建一个副本RTCPeerConnection,因为这将消除您以前的webRTC会话。

但是,在使用React的WebRTC应用程序中,可能不同的组件需要访问RTCPeerConnection对象(例如,它可能是在应用程序中的顶级组件的安装上实例化,但是在某些UI组件中就像模态一样在接受调用的树的深处,您想要在RTCPeerConnection上调用方法来创建对收到的webRTC商品的答案。或者可能是深层嵌套的组件需要发起调用)。是唯一的解决办法是将对象作为道具传递给组件树吗?有没有办法将redux用于这样的复杂对象?

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

1 个答案:

答案 0 :(得分:1)

Redux应用程序中" socket"类连接对象(websockets,Firebase等)的标准位置是中间件。需要告诉套接字执行某些操作的应用程序的任何部分都可以调度由中间件拦截的操作,并且中间件可以调度操作以更新状态以响应收到的消息。

我的Middleware - Sockets and AdaptersRedux addons catalog部分中有几十个现有的各种套接字中间件示例。

<强>更新

以下是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);
        }    
    }
}