webRTC - 区分临时断开或故障与永久断开或故障

New*_*bie 5 javascript webrtc

更新

看来我可以按照此处myPeerConnection.getStats()所述进行操作,我可以测量发送或接收的字节数。如果它们增加,则意味着我们已连接,并且ICE 状态将被视为临时状态。否则,它是永久性的。但现在我很困惑应该测量哪个字节。有、、和。disconnectedinbound-rtpoutbound-rtpremote-inbound-rtpremote-outbound-rtp

我想确保双方实际上都在互相接收数据。那么我应该从以上四个方面来衡量什么呢?

原来的

有时,在不稳定的网络上,ICE 状态可能会更改为“已断开连接”,并且通常会尝试自行恢复。“失败”状态将需要 ICE 重新协商。但在某些情况下,另一个对等点刚刚失去连接或死亡,在这种情况下,我将得到“断开连接”,然后在一段时间后进入“失败”状态。我需要知道对等连接何时仍处于活动状态以及何时已断开,以便我可以采取适当的操作。

    function handleICEConnectionStateChangeEvent(event) {
  log("*** ICE connection state changed to " + myPeerConnection.iceConnectionState);
      switch(myPeerConnection.iceConnectionState) {
        case "closed": // This means connection is shut down and no longer handling requests.
            hangUpCall(); //Hangup instead of closevideo() because we want to record call end in db
            break;
        case "failed": // This will not restart ICE negotiation on its own and must be restarted/
            myPeerConnection.restartIce();
            break;
        case "disconnected": 
             //This will resolve on its own. No need to close connection.
             //But in case the other peer connection is dead we want to call the below function.
            //hangUpCall(); //Hangup instead of closevideo() because we want to record call end in db
            //break;
      }
    }
Run Code Online (Sandbox Code Playgroud)

我想要类似的东西

case "disconnected":
   if(!otherPeerConnected){
       hangUpCall();
   }
Run Code Online (Sandbox Code Playgroud)

有办法做到这一点吗?

谢谢

New*_*bie 4

从MDN我得到了这个

入站rtp: An RTCInboundRtpStreamStats object providing statistics about inbound data being received from remote peers. Since this only provides statistics related to inbound data, without considering the local peer's state, any values that require knowledge of both, such as round-trip time, is not included. This report isn't available if there are no connected peers

我现在将使用它,如下所示,以防其他人将来需要它。

function handleICEConnectionStateChangeEvent(event) {
  log("*** ICE connection state changed to " + myPeerConnection.iceConnectionState);

  switch(myPeerConnection.iceConnectionState) {
    case "closed": // This means connection is shut down and no longer handling requests.
        hangUpCall(); //Hangup instead of closevideo() because we want to record call end in db
        break;
    case "failed":
        checkStatePermanent('failed');
        break;
    case "disconnected":
        checkStatePermanent('disconnected');
        break;
  }
}


 const customdelay = ms => new Promise(res => setTimeout(res, ms));


async function checkStatePermanent (iceState) {
    videoReceivedBytetCount = 0;
    audioReceivedByteCount = 0;

    let firstFlag = await isPermanentDisconnect();

    await customdelay(2000);

    let secondFlag = await isPermanentDisconnect(); //Call this func again after 2 seconds to check whether data is still coming in.

    if(secondFlag){ //If permanent disconnect then we hangup i.e no audio/video is fllowing
        if (iceState == 'disconnected'){
            hangUpCall(); //Hangup instead of closevideo() because we want to record call end in db
        }
    }
    if(!secondFlag){//If temp failure then restart ice i.e audio/video is still flowing
         if(iceState == 'failed') {
            myPeerConnection.restartIce();
        }
    }
};

var videoReceivedBytetCount = 0;
var audioReceivedByteCount = 0; 


async function isPermanentDisconnect (){
    var isPermanentDisconnectFlag = false;
    var videoIsAlive = false;
    var audioIsAlive = false;

    await myPeerConnection.getStats(null).then(stats => {
        stats.forEach(report => {
            if(report.type === 'inbound-rtp' && (report.kind === 'audio' || report.kind  === 'video')){ //check for inbound data only
                if(report.kind  === 'audio'){
                    //Here we must compare previous data count with current
                    if(report.bytesReceived > audioReceivedByteCount){
                        // If current count is greater than previous then that means data is flowing to other peer. So this disconnected or failed ICE state is temporary
                        audioIsAlive = true;
                    } else {
                        audioIsAlive = false;
                        
                    }
                    audioReceivedByteCount = report.bytesReceived;
                }
                if(report.kind  === 'video'){
                    if(report.bytesReceived > videoReceivedBytetCount){
                        // If current count is greater than previous then that means data is flowing to other peer. So this disconnected or failed ICE state is temporary
                        videoIsAlive = true;
                    } else{
                        videoIsAlive = false;
                    }
                    videoReceivedBytetCount = report.bytesReceived;
                }
                if(audioIsAlive || videoIsAlive){ //either audio or video is being recieved.
                    isPermanentDisconnectFlag = false; //Disconnected is temp
                } else {
                    isPermanentDisconnectFlag = true;
                }
            }
        })
    });

    return isPermanentDisconnectFlag;
}
Run Code Online (Sandbox Code Playgroud)