Tutorial: 检测通话前的网络质量

检测通话前的网络质量

在进房之前,检测用户的网络质量,可以提前判断用户当下的网络质量情况。若用户网络质量太差,应建议用户更换网络环境,以保证正常通话质量。

本文主要介绍如何基于 NETWORK_QUALITY 事件及 Client.getTransportStats 接口实现通话前网络质量检测。

注:通话过程中网络质量检测请直接使用: NETWORK_QUALITY 事件。

实现流程

由于 NETWORK_QUALITY 事件是进房之后,每两秒抛出一次。因此可在本地创建两个 Client,进入同一个用于测试的房间,其中一个 Client 推流,另一个 Client 拉流,持续 15s 左右,统计出平均网络质量,从而大致判断出上下行网络情况。

数据准备

let uplinkClient = null; // 用于检测上行网络质量
let downlinkClient = null; // 用于检测下行网络质量
let localStream = null; // 用于测试的流
let testResult = {
  // 记录上行网络质量数据
  uplinkNetworkQualities: [],
  // 记录下行网络质量数据
  downlinkNetworkQualities: [],
  // 记录 rtt 数据
  rttList: [],
  average: {
    rtt: 0,
    uplinkNetworkQuality: 0,
    downlinkNetworkQuality: 0
  }
}

检测网络延迟

使用 Client.getTransportStats 接口检测网络延迟,该接口依赖于 uplinkClient。

async function testNetworkDelay() {
  if (!uplinkClient) {
    return;
  }
  const { rtt } = await uplinkClient.getTransportStats();
  testResult.rttList.push(rtt);
}

检测上行网络质量

使用 uplinkClient 来推流,检测上行网络质量

async function testUplinkNetworkQuality() {
  uplinkClient = TRTC.createClient({
    sdkAppId: 0, // 填写 sdkAppId
    userId: 'user_uplink_test',
    userSig: '', // uplink_test 的 userSig
    mode: 'rtc'
  });

  localStream = TRTC.createStream({ audio: true, video: true });
  // 根据实际业务场景设置 video profile
  localStream.setVideoProfile('480p'); 
  await localStream.initialize();

  uplinkClient.on('network-quality', event => {
    const { uplinkNetworkQuality } = event;
    testResult.uplinkNetworkQualities.push(uplinkNetworkQuality);
  });

  // 加入用于测试的房间,房间号需要随机,避免冲突
  await uplinkClient.join({ roomId: 8080 }); 
  await uplinkClient.publish(localStream);
}

检测下行网络质量

通过 downlinkClient 来拉取 uplinkClient 推的流,检测下行网络质量

async function testDownlinkNetworkQuality() {
  downlinkClient = TRTC.createClient({
    sdkAppId: 0, // 填写 sdkAppId
    userId: 'user_downlink_test',
    userSig: '', // userSig
    mode: 'rtc'
  });

  downlinkClient.on('stream-added', async event => {
    async downlinkClient.subscribe(event.stream, { audio: true, video: true });
		// 订阅成功后开始监听网络质量事件
    downlinkClient.on('network-quality', event => {
      const { downlinkNetworkQuality } = event;
      testResult.downlinkNetworkQualities.push(downlinkNetworkQuality);
    });
  })
  downlinkClient.join({ roomId: 8080 });
}

开始检测

testUplinkNetworkQuality();
testDownlinkNetworkQuality();

// 检测倒计时 15s
let countDown = 15; 
const intervalId = setInterval(() => {
  countDown--;
  testNetworkDelay();
  if (countDown === 0) {
    // 计算平均网络延迟
    testResult.average.rtt = Math.ceil(
    	testResult.rttList.reduce((value, current) => value + current, 0) / testResult.rttList.length
    );
    
    // 计算上行平均网络质量
    testResult.average.uplinkNetworkQuality = Math.ceil(
    	testResult.uplinkNetworkQualities.reduce((value, current) => value + current, 0) / testResult.uplinkNetworkQualities.length
    );
    
    // 计算下行平均网络质量
    testResult.average.downlinkNetworkQuality = Math.ceil(
    	testResult.downlinkNetworkQualities.reduce((value, current) => value + current, 0) / testResult.downlinkNetworkQualities.length
    );
    
    // 检测结束,清理相关状态。
    uplinkClient.leave();
    downlinkClient.leave();
    localStream.close();
    clearInterval(intervalId);
  }
});

检测结果分析

经过上述步骤,可以拿到上行平均网络质量、下行平均网络质量、平均网络延迟三个数据,其中网络质量的枚举值如下所示:

数值 含义
0 网络状况未知,表示当前 client 实例还没有建立上行/下行连接
1 网络状况极佳
2 网络状况较好
3 网络状况一般
4 网络状况差
5 网络状况极差
6 网络连接已断开 注意:若下行网络质量为此值,则表示所有下行连接都断开了

建议:当网络质量不等于 1,2,3 时,引导用户检查网络并尝试更换网络环境,否则难以保证正常的音视频通话。

API 调用时序

network-quality-call-sequence