在 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应用程序中的功能?