webRTC - Differentiate between temporary disconnect or failure and permanant

此生再无相见时 提交于 2021-01-27 18:15:06

问题


UPDATE

It seems I can do myPeerConnection.getStats() as described here I can measure the bytes sent or recieved. If they increase that means we are connected and the disconnected ICE state will be treated as temporary. otherwise, it is permanent. But now I am confused about which byte I should measure. There inbound-rtp, outbound-rtp, remote-inbound-rtp and remote-outbound-rtp.

I want to make sure that both sides are actually receiving data from each other. So what should I measure from the above four?

ORIGINAL

Sometimes on unstable networks ICE state can change to 'Disconnected' and will normally try to recover on its own. 'Failed' state will need ICE renegotiated. But there will be cases when the other peer has just lost connection or died and in that case I will get 'Disconnected' and then after sometime 'Failed' states. I need to know when the peer connection is still alive and when it is dead so that I can take appropriate action.

    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;
      }
    }

I would like something like

case "disconnected":
   if(!otherPeerConnected){
       hangUpCall();
   }

Is there anyway to do this?

Thank you


回答1:


from MDN I got this

inbound-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

I am now going to use that as shown below, in case anyone else wants it in future.

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;
}


来源:https://stackoverflow.com/questions/63582725/webrtc-differentiate-between-temporary-disconnect-or-failure-and-permanant

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!