【问题标题】:Detecting that the peer's browser was closed in a webrtc videochat在 webrtc 视频聊天中检测到对等方的浏览器已关闭
【发布时间】:2014-02-09 14:42:11
【问题描述】:

我一直在实施 webrtc 视频聊天。

除了对等端关闭浏览器的情况外,一切都很顺利。

我一直在尝试通过在远程媒体流上实现 onended 回调来处理此事件。不过,这个回调似乎从未被调用过。

如何检测对端的浏览器是否已关闭或另一端的连接已完成?

【问题讨论】:

    标签: javascript html video-streaming html5-video webrtc


    【解决方案1】:

    您可以使用 ICE 连接状态来确定这一点。如果您断开一个对等点,则需要几秒钟(约 5 秒?)才能识别它,但即使没有信号服务器也能正常工作。

    (假设您调用了对等连接pc

    pc.oniceconnectionstatechange = function() {
        if(pc.iceConnectionState == 'disconnected') {
            console.log('Disconnected');
        }
    }
    

    【讨论】:

    • 由于某种原因,这个事件似乎没有在我的实现中被触发(Chrome 40)
    • @LouisLC 我刚刚检查过,对我来说它在版本 40.0.2214.115 上运行良好。也许您应该检查oniceconnectionstatechange 的拼写是否正确? Afaik 连接应该首先设置完成,然后才能触发,但我建议您在 spec 中查找它,看看我是否遗漏了什么。
    • 是的,这确实是一个简单的拼写问题!谢谢你玛丽恩。您能否编辑您的初始答案以将您的“onineconnectionstatechange”替换为“oniceconnectionstatechange”?我不允许编辑。
    • @LouisLC 现在我明白了,我自己写错了。对不起!昨天甚至没有看到(尽管在我自己的代码版本中是正确的)。
    【解决方案2】:

    使用信令网关向您要离开的所有已连接对等方发送消息;像这样:

    window.addEventListener('beforeunload', function () {
        userLeft();
    }, false);
    
    window.addEventListener('keyup', function (e) {
        if (e.keyCode == 116)
            userLeft();
    }, false);
    
    function userLeft() {
        signalingGateway.send({
            userLeft: true,
            whoLeft: 'user-id'
        });
    }
    
    signalingGateway.on('message', function (signal) {
        if (signal.userLeft && signal.whoLeft != 'current-user-id') {
            var relevantPeer = listOfPeers[signal.whoLeft];
            if (relevantPeer) {
                relevantPeer.close();
                relevantPeer = null;
            }
    
            var relevantLocalStreams = listOfLocalStreams[signal.whoLeft];
            if (relevantLocalStreams.length) {
                for (var i = 0; i < relevantLocalStreams.length; i++) {
                    if (relevantLocalStreams[i].stop) {
                        relevantLocalStreams[i].stop();
                    }
    
                    // it is suggested to stop media tracks instead!
                }
            }
        }
    });
    

    【讨论】:

    • 请记住,使用getStats API可以检测远程媒体流是否停止接收RTP数据包;但是,您需要依赖预定义的变量/名称!
    • 我暂时没有完整的信令网关。
    • 你好 Muaz,我真的很喜欢你的 webRTC 作品!我很好奇您为什么建议在这里使用信令网关,是否不可能通过 DataChannel 直接向 onbeforeunload 的对等方发送消息?如果用户的浏览器/PC 崩溃,onbeforeunload 方式也会失败。在这种情况下是否有任何解决方法?一种方法是在 websocket 信令服务器端进行心跳并以这种方式检测断开连接,但也许您可以提出更好的建议?
    • iceState=disconnected 依赖于在会话的生命周期内不断发出的 STUN 绑定请求。这种方法在实时应用程序中不被认为是一种可靠的解决方案,这就是所有 WebRTC 服务提供商(TokBox、EasyRTC 等)处理存在/等的原因。信令端检测。手动检查服务器上的心跳或收听disconnect evens 可以产生更好/可靠的体验。 DataChannels 可以在实时会话中多次自动断开连接,这就是为什么channel.onclose 不是一个好的处理程序。如果您尝试发送大于 64k 等大小的消息,则频道可能会关闭。
    【解决方案3】:

    我正在使用这样的解决方案:

    const connection = new RTCPeerConnection(configuration);
    connection.onconnectionstatechange = () => {
        const connectionStatus = connection.connectionState;
        if (["disconnected", "failed", "closed"].includes(connectionStatus)) {
            console.log("disconnected");
        }
    };
    

    【讨论】:

      【解决方案4】:

      我也有这个问题。我已经通过在所需时刻关闭连接(例如在析构函数上)解决了这个问题。

      A B

      ...

      关闭(A); // 此后,B 的 ice 状态几乎会立即变为 'kDisconnected'。

      【讨论】:

        【解决方案5】:

        随便用

         connection.onclose = function(event){
            event.useid // gives the connection closed userid
         }
        

        【讨论】:

        • 在您的示例中,什么类型的变量是“连接”?是数据通道吗?因为数据通道没有检测到关闭远程对等体
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多