【发布时间】:2014-02-09 14:42:11
【问题描述】:
我一直在实施 webrtc 视频聊天。
除了对等端关闭浏览器的情况外,一切都很顺利。
我一直在尝试通过在远程媒体流上实现 onended 回调来处理此事件。不过,这个回调似乎从未被调用过。
如何检测对端的浏览器是否已关闭或另一端的连接已完成?
【问题讨论】:
标签: javascript html video-streaming html5-video webrtc
我一直在实施 webrtc 视频聊天。
除了对等端关闭浏览器的情况外,一切都很顺利。
我一直在尝试通过在远程媒体流上实现 onended 回调来处理此事件。不过,这个回调似乎从未被调用过。
如何检测对端的浏览器是否已关闭或另一端的连接已完成?
【问题讨论】:
标签: javascript html video-streaming html5-video webrtc
您可以使用 ICE 连接状态来确定这一点。如果您断开一个对等点,则需要几秒钟(约 5 秒?)才能识别它,但即使没有信号服务器也能正常工作。
(假设您调用了对等连接pc)
pc.oniceconnectionstatechange = function() {
if(pc.iceConnectionState == 'disconnected') {
console.log('Disconnected');
}
}
【讨论】:
oniceconnectionstatechange 的拼写是否正确? Afaik 连接应该首先设置完成,然后才能触发,但我建议您在 spec 中查找它,看看我是否遗漏了什么。
使用信令网关向您要离开的所有已连接对等方发送消息;像这样:
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!
}
}
}
});
【讨论】:
iceState=disconnected 依赖于在会话的生命周期内不断发出的 STUN 绑定请求。这种方法在实时应用程序中不被认为是一种可靠的解决方案,这就是所有 WebRTC 服务提供商(TokBox、EasyRTC 等)处理存在/等的原因。信令端检测。手动检查服务器上的心跳或收听disconnect evens 可以产生更好/可靠的体验。 DataChannels 可以在实时会话中多次自动断开连接,这就是为什么channel.onclose 不是一个好的处理程序。如果您尝试发送大于 64k 等大小的消息,则频道可能会关闭。
我正在使用这样的解决方案:
const connection = new RTCPeerConnection(configuration);
connection.onconnectionstatechange = () => {
const connectionStatus = connection.connectionState;
if (["disconnected", "failed", "closed"].includes(connectionStatus)) {
console.log("disconnected");
}
};
【讨论】:
我也有这个问题。我已经通过在所需时刻关闭连接(例如在析构函数上)解决了这个问题。
A B
...
关闭(A); // 此后,B 的 ice 状态几乎会立即变为 'kDisconnected'。
【讨论】:
随便用
connection.onclose = function(event){
event.useid // gives the connection closed userid
}
【讨论】: