在 webrtc 视频聊天中检测到对等方的浏览器已关闭

Posted

技术标签:

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

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

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

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

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

【问题讨论】:

【参考方案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
 

【讨论】:

在您的示例中,什么类型的变量是“连接”?是数据通道吗?因为数据通道没有检测到关闭远程对等体

以上是关于在 webrtc 视频聊天中检测到对等方的浏览器已关闭的主要内容,如果未能解决你的问题,请参考以下文章

如何实施“谁在说话?” webrtc ios应用程序中的功能?

web技术分享| 实现WebRTC多个对等连接

web技术分享| 实现WebRTC多个对等连接

TSINGSEE青犀视频Webrtc实时通信的构建流程——PeerConnection对等通信的实现方式

Flutter webrtc音频无法在android上运行

通过 WebRTC 将视频对等点录制到服务器时如何处理数据包丢失