# 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'>↓</span>" + screenConnection.downloadBitrate + " <span class='jitsipopover_orange'>↑</span>" + screenConnection.uploadBitrate;
    						var screenPacket = "数据包 : <span class='jitsipopover_green'>↓</span>" + screenConnection.downloadPacket + " <span class='jitsipopover_orange'>↑</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;
    				    }
    	            }
    			}
    		}
    	}
    }