# Tutorial: 检测网络质量

在通话过程中，检测用户的网络质量，可以判断用户当下的网络质量情况。若用户网络质量太差，应建议用户检查网络或尝试更换网络，以保证正常通话质量。

本文主要介绍如何基于RoomCallback.connection_indicator事件实现通话过程网络质量检测。

## 通话过程中的网络质量检测

    room.addCallback(RoomCallback.mcu_peerconnection_completed, onMCUPeerConnectionCompleted);
    room.addCallback(RoomCallback.connection_indicator, onConnectionIndicator);

    function onMCUPeerConnectionCompleted() {
        var connectionInfoInterval = 1000; //网络情况收集计算频率
        room.connectionInfoCollector.start(connectionInfoInterval); //开始收集网络情况,不填写频率参数，默认1000毫秒

        room.connectionInfoCollector.stop();  //停止收集网络情况
    }

    /**
     * 网络状态回调
     */
    function onConnectionIndicator(connectionIndicator) {
            if(connectionIndicator) {
                var roomConnection = connectionIndicator.getRoomConnection();
                if(roomConnection) {
                    var localAddress = "本地地址: " + roomConnection.localAddress;
                    var localPort = "本地端口: " + roomConnection.localPort;
                    var localProtocol = "本地协议: " + roomConnection.localProtocol;

                    var remoteAddress = "远端地址: " + roomConnection.remoteAddress;
                    var remotePort = "远端端口: " + roomConnection.remotePort;
                    var remoteProtocol = "远端协议: " + roomConnection.remoteProtocol;

                    var bitrate = "流量: 下行/" + roomConnection.downloadBitrate + ", 上行/" + roomConnection.uploadBitrate;
                    var packet = "数据包:下行/" + roomConnection.downloadPacket + ", 上行/" + roomConnection.uploadPacket;
                    var packetLost = "数据包丢包数: 下行/" + roomConnection.downloadPacketLost + ", 上行/" + roomConnection.uploadPacketLost;
                    var packetLossRate = "数据包丢包率: 下行/" + roomConnection.downloadPacketLostRate + ", 上行/" + roomConnection.uploadPacketLostRate;
                    var currentRoundTripTime = "当前的往返时间(RTT): " + roomConnection.currentRoundTripTime;
                    var totalRoundTripTime = "累计的往返时间(RTT): " + roomConnection.totalRoundTripTime;
                }
           }
    }

## 结果分析

经过上述步骤，可以拿到上下行丢包率来评估网络质量。

## 另外也提供了回调接口来获取到音频流、视频流、桌面共享流的相关检测指标

    room.addCallback(RoomCallback.mcu_peerconnection_completed, onMCUPeerConnectionCompleted);
    room.addCallback(RoomCallback.connection_indicator, onConnectionIndicator);

    function onMCUPeerConnectionCompleted() {
        var connectionInfoInterval = 1000; //网络情况收集计算频率
        room.connectionInfoCollector.start(connectionInfoInterval); //开始收集网络情况,不填写频率参数，默认1000毫秒

        room.connectionInfoCollector.stop();  //停止收集网络情况
    }

    /**
     * 音频流、视频流、桌面共享流的相关指标检测回调
     */
    function onConnectionIndicator(connectionIndicator) {
        if(connectionIndicator) {
                var participants = room.getParticipants();
                participants.forEach(function(user) {

                    //音频流相关
                    if(user && user.audio && (user.audio.status == 2 || user.audio.status == 3)){
                      var audioConnection = connectionIndicator.getAudioConnection(user.id);
                      if(audioConnection) {
                          var audioBitrate = "流量: 下行/" + audioConnection.downloadBitrate + ", 上行/" + audioConnection.uploadBitrate;
                          var audioPacket = "数据包: 下行/" + audioConnection.downloadPacket + ", 上行/" + audioConnection.uploadPacket;
                          var audioPacketLost = "数据包丢包数: "+ audioConnection.packetsLost;
                          var audioPacketLostRate = "数据包丢包率 : "+ audioConnection.packetLostRate;
                          var ssrc = "ssrc : " + audioConnection.ssrc;
                          var trackId = "trackId : " + audioConnection.trackId;
                          var payloadType = "payloadType : " + audioConnection.payloadType;
                          var mimeType = "mimeType : " + audioConnection.mimeType;;
                          var clockRate = "clockRate : " + audioConnection.clockRate;
                      }
                    }

                    //视频流相关
                    if(user && user.videos && user.videos.length>0){
                        for(var i=0; i<user.videos.length; i++){
                            var video = user.videos[i];
                            if(video.status == 2){
                                var videoConnection = connectionIndicator.getVideoConnection(user.id, video.id);
                                if(videoConnection) {
                                    var videoBitrate = "流量: 下行/" + videoConnection.downloadBitrate + ", 上行/" + videoConnection.uploadBitrate;
                                    var videoPacket = "数据包: 下行/" + videoConnection.downloadPacket + ", 上行/" + videoConnection.uploadPacket;
                                    var videoPacketLost = "数据包丢包数 : "+ videoConnection.packetsLost;
                                    var videoPacketLostRate = "数据包丢包率 : "+ videoConnection.packetLostRate;
                                    var resolution = "分辨率 : " + videoConnection.resolution;
                                    var frameRate = "帧率 : " + videoConnection.frameRate;
                                    var qpSum = "媒体数据包的总量化值(qpSum) : " + videoConnection.qpSum;
                                    var framesEncoded = "已编码帧的数量 : " + videoConnection.framesEncoded;
                                    var framesDecoded = "已解码帧的数量 : " + videoConnection.framesDecoded;
                                    var perFrameQP = "每个视频帧的平均量化值(perFrameQP) : " + videoConnection.perFrameQP;
                                    var ssrc = "ssrc : " + videoConnection.ssrc;
                                    var trackId = "trackId : " + videoConnection.trackId;
                                    var payloadType = "payloadType : " + videoConnection.payloadType;
                                    var mimeType = "mimeType : " + videoConnection.mimeType;
                                    var clockRate = "clockRate : " + videoConnection.clockRate;
                                }
                            }
                    }

                    //桌面共享流相关
                    if(user && user.screen  && user.screen.status == 2 ){
                        var screenConnection = connectionIndicator.getScreenConnection(user.id);
                        if(screenConnection) {
                            var screenBitrate = "流量 : <span class='jitsipopover_green'>&darr;</span>" + screenConnection.downloadBitrate + " <span class='jitsipopover_orange'>&uarr;</span>" + screenConnection.uploadBitrate;
                            var screenPacket = "数据包 : <span class='jitsipopover_green'>&darr;</span>" + screenConnection.downloadPacket + " <span class='jitsipopover_orange'>&uarr;</span>" + screenConnection.uploadPacket;
                            var screenPacketLost = "数据包丢包数 : "+ screenConnection.packetsLost;
                            var screenPacketLostRate = "数据包丢包率 : "+ screenConnection.packetLostRate;
                            var resolution = "分辨率 : " + screenConnection.resolution;
                            var frameRate = "帧率 : " + screenConnection.frameRate;
                            var ssrc = "ssrc : " + screenConnection.ssrc;
                            var trackId = "trackId : " + screenConnection.trackId;
                            var payloadType = "payloadType : " + screenConnection.payloadType;
                            var mimeType = "mimeType : " + screenConnection.mimeType;
                            var clockRate = "clockRate : " + screenConnection.clockRate;
                        }
                    }
                }
            }
        }
    }