• 서비스
  • 가격
  • 리소스
  • 기술지원

네트워크 품질의 모니터링

네트워크 품질을 더 잘 인식할 수 있도록 사용자가 통화 전에 속도 측정을 수행하고 통화 중 네트워크 품질과 연결 상태를 모니터링하며, 해당 UI 인터페이스 상호작용과 알림을 제공할 것을 권장합니다. 이렇게 하면 사용자가 현재 네트워크 품질을 알고 네트워크 설정을 적시에 조정하여 최적의 통화 효과를 달성할 수 있습니다.

통화 전 네트워크 속도을 측정하세요

일반 사용자는 네트워크 상황을 인지하기 어렵기 때문에, 현재 네트워크 품질을 평가하고 통화의 최적 효과를 위해 네트워크를 적시에 조정할 수 있도록 통화 전 속도 측정을 수행할 것을 권장합니다.
속도 측정의 원리는 SDK가 서버 노드에 일부 탐색 패킷을 전송한 후 회신 패킷의 품질을 통계하고, 측정 결과를 콜백 인터페이스를 통해 통보해줍니다.아래 그림과 같습니다.



통화 전 속도 측정의 장점
속도 측정 결과는 SDK의 서버 선택 전략을 최적화하는 데 사용되므로, 최적의 서버를 선택할 수 있도록 사용자의 첫 통화 전에 한 번 속도 측정을 수행할 것을 권장합니다.
테스트 결과가 매우 좋지 않다면, 사용자에게 더 나은 네트워크 환경을 선택하도록 눈에 띄는 UI로 안내할 수 있습니다.

startSpeedTest 속도 측정

Android
iOS
Windows
//네트워크 속도 측정을 시작하는 예제 코드, sdkAppId와 UserSig가 필요합니다. (받은 방법은 기본 기능 참조하세요)
// 로그인 후 테스트를 시작하는 것을 예로 들면
public void onLogin(String userId, String userSig)
{
TRTCCloudDef.TRTCSpeedTestParams params = new TRTCCloudDef.TRTCSpeedTestParams();
params.sdkAppId = GenerateTestUserSig.SDKAPPID;
params.userId = mEtUserId.getText().toString();
params.userSig = GenerateTestUserSig.genTestUserSig(params.userId);
params.expectedUpBandwidth = Integer.parseInt(expectUpBandwidthStr);
params.expectedDownBandwidth = Integer.parseInt(expectDownBandwidthStr);
// sdkAppID는 콘솔에서 받은 실제 애플리케이션의 AppID입니다.
trtcCloud.startSpeedTest(params);
}

// 속도 측정 결과를 모니터링하고, TRTCCloudListener를 상속하여 다음과 같은 방법으로 구현됩니다.
void onSpeedTestResult(TRTCCloudDef.TRTCSpeedTestResult result)
{
// 속도 측정이 완료되면 속도 측정 결과가 콜백됩니다.
}Android
//네트워크 속도 측정을 시작하는 예제 코드는 sdkAppId와 UserSig가 필요합니다. (받은 방법은 기본 기능 참조하세요)
// 로그인 후 테스트를 시작하는 것을 예로 들면
- (void)onLogin:(NSString *)userId userSig:(NSString *)userSid
{
TRTCSpeedTestParams *params;
// sdkAppID는 콘솔에서 받은 실제 애플리케이션의 AppID입니다.
params.sdkAppID = sdkAppId;
params.userID = userId;
params.userSig = userSig;
// 예상 업로드 대역폭 (kbps, 범위: 10 ~ 5000, 0인 경우 테스트하지 않음)
params.expectedUpBandwidth = 5000;
// 예상 다운로드 대역폭 (kbps, 범위: 10 ~ 5000, 0인 경우 테스트하지 않음)
params.expectedDownBandwidth = 5000;
[trtcCloud startSpeedTest:params];
}
- (void)onSpeedTestResult:(TRTCSpeedTestResult *)result {
// 속도 측정이 완료되면 속도 측정 결과로 돌아갑니다.
}
//네트워크 속도 측정을 시작하는 예제 코드는 sdkAppId와 UserSig가 필요합니다. (받은 방법은 기본 기능 참조하세요)
// 로그인 후 테스트를 시작하는 것을 예로 들면
void onLogin(const char* userId, const char* userSig)
{
TRTCSpeedTestParams params;
// sdkAppID는 콘솔에서 받은 실제 애플리케이션의 AppID입니다.
params.sdkAppID = sdkAppId;
params.userId = userid;
param.userSig = userSig;
// 예상 업로드 대역폭 (kbps, 범위: 10 ~ 5000, 0인 경우 테스트하지 않음)
param.expectedUpBandwidth = 5000;
// 예상 다운로드 대역폭 (kbps, 범위: 10 ~ 5000, 0인 경우 테스트하지 않음)
param.expectedDownBandwidth = 5000;
trtcCloud->startSpeedTest(params);
}

// 속도 측정 결과를 모리터링합니다.
void TRTCCloudCallbackImpl::onSpeedTestResult(
const TRTCSpeedTestResult& result)
{
// 속도 측정이 완료되면 속도 측정 결과가 콜백됩니다.
}
속도 측정 결과(TRTCSpeedTestResult)에 다음과 같은 필드가 포함됩니다.
필드
의미
의미에 대한 설명
success
성공 여부
이번 테스트의 성공 여부
errMsg
에러 정보
대역폭 테스트의 상세 에러 정보
ip
서버 IP
속도 측정 서버의 IP
quality
네트워크 품질에 대한 점수
평가 알고리즘으로 측정된 네트워크 품질은 loss가 낮을수록, rtt가 작을수록 점수가 높아집니다.
upLostRate
업로드 패킷의 손실률
범위는 [0 - 1.0]이며, 예를 들어 0.3은 서버에 10개의 데이터 패킷을 전송할 때 3개가 중간에 손실될 수 있음을 나타냅니다.
downLostRate
다운로드 패킷의 손실률
범위는 [0 - 1.0]이며, 예를 들어 0.2는 서버에서 10개의 데이터 패킷을 수신할 때 2개가 중간에 손실될 수 있음을 나타냅니다.
rtt
네트워크 지연
SDK와 서버 간의 왕복에 소요되는 시간을 나타내며, 이 값은 작을수록 좋으며 일반적인 수치는 10ms - 100ms 에 있습니다.
availableUpBandwidth
업로드 대역폭
예상 업로드 대역폭의 단위는 kbps이며 -1은 유효하지 않은 값을 의미합니다
availableDownBandwidth
다운로드 대역폭
예상 다운로드 대역폭의 단위는 kbps이고 -1은 유효하지 않은 값을 의미합니다

도구 속도의 측정

인터페이스 호출 방식으로 네트워크 속도 측정을 원하지 않는 경우, Real-Time Communication Engine (RTC Engine)은 데스크톱용 네트워크 속도 측정 도구 프로그램을 제공하여 상세한 네트워크 품질 정보를 신속하게 확인할 수 있도록 해줍니다. 사용자는 자신의 플랫폼에 따라 다음 프로그램을 선택하여 다운로드할 수 있습니다. 이 프로그램은 빠른 테스트와 지속적인 테스트 두 가지 옵션을 제공합니다:
Mac
지표
의미
WiFi Quality
Wi-Fi 신호 품질
DNS RTT
텐센트 클라우드의 속도 측정 도메인 분석에 소요된 시간
MTR
MTR은 네트워크 테스트 도구이고 클라이언트에서 RTC Engine 노드까지의 패킷 손실률과 지연 시간을 탐지할 수 있으며, 라우팅의 각 홉에 대한 구체적인 정보를 확인할 수 있습니다.
UDP Loss
클라이언트에서 RTC Engine 노드까지의 UDP 패킷 손실률
UDP RTT
클라이언트에서 RTC Engine 노드까지의 UDP 지연 시간
Local RTT
클라이언트에서 로컬 게이트웨이까지의 지연 시간
Upload
예상 업로드 대역폭
Download
예상 다운로드 대역폭
주의:
영상 통화 중에는 통화 품질에 영향을 줄 수 있으니 테스트하지 마십시오.
속도 측정 자체로 인해 일정량의 데이터가 소모되어 극소량의 추가 요금이 발생할 수 있습니다(기본적으로 무시할 수 있는 수준).

통화 중의 네트워크 모니터링

사용자가 통화 중 발생할 수 있는 네트워크 변동을 더 명확하게 인지할 수 있도록 통화 화면에 해당 UI 알림을 추가하는 것이 좋습니다. 특히 네트워크 상태가 좋지 않을 때 알림을 통해 사용자가 변화를 감지하고 네트워크 상황을 개선하기 위해 적절히 대처할 수 있도록 해야 합니다.

onNetworkQuality 로컬 네트워크 품질의 모니터링

네트워크 품질에 대한 onNetworkQuality 콜백 이벤트는 2초마다 현재 네트워크 품질을 보고하며, 매개변수로 localQuality와 remoteQuality 두 부분을 포함합니다.
localQuality: 현재 네트워크 품질을 나타내며, Excellent, Good, Poor, Bad, VeryBad, Down의 6개 등급으로 구분됩니다.
remoteQuality: 원격 사용자의 네트워크 품질을 나타내며, 이는 배열로 각 요소는 하나의 원격 사용자 네트워크 품질을 나타냅니다.
Quality
명칭
설명
0
Unknown
감지되지 않음
1
Excellent
현재 네트워크 상태가 매우 좋습니다.
2
Good
현재 네트워크 상태가 비교적 좋습니다
3
Poor
현재 네트워크 상태가 보통입니다
4
Bad
현재 네트워크 상태가 좋지 않아서 뚜렷한 끊김 및 통화 지연이 발생할 수 있습니다.
5
VeryBad
현재 네트워크 상태가 매우 나쁩니다. RTC Engine이 간신히 연결을 유지할 수 있지만 통신 품질은 보장할 수 없습니다.
6
Down
현재 네트워크가 RTC Engine의 최소 요구 사항을 충족하지 않아 정상적인 음성 및 영상 통화를 할 수 없습니다.
네트워크 품질(onNetworkQuality)을 모니터링하고 화면에 해당 알림을 표시하면 됩니다.
Android
iOS&Mac
Windows
// onNetworkQuality 콜백을 모니터링하여 현재 네트워크 상태 변화를 감지합니다.
@Override
public void onNetworkQuality(TRTCCloudDef.TRTCQuality localQuality,
ArrayList<trtcclouddef.trtcquality> remoteQuality)
{
// Get your local network quality
switch(localQuality) {
case TRTCQuality_Unknown:
Log.d(TAG, "SDK has not yet sensed the current network quality.");
break;
case TRTCQuality_Excellent:
Log.d(TAG, "The current network is very good.");
break;
case TRTCQuality_Good:
Log.d(TAG, "The current network is good.");
break;
case TRTCQuality_Poor:
Log.d(TAG, "The current network quality barely meets the demand.");
break;
case TRTCQuality_Bad:
Log.d(TAG, "The current network is poor, and there may be significant freezes and call delays.");
break;
case TRTCQuality_VeryBad:
Log.d(TAG, "The current network is very poor, the communication quality cannot be guaranteed");
break;
case TRTCQuality_Down:
Log.d(TAG, "The current network does not meet the minimum requirements.");
break;
default:
break;
}
// Get the network quality of remote users
for (TRTCCloudDef.TRTCQuality info : arrayList) {
Log.d(TAG, "remote user : = " + info.userId + ", quality = " + info.quality);
}
}
// onNetworkQuality 콜백을 모니터링하여 현재 네트워크 상태 변화를 감지합니다.
- (void)onNetworkQuality:(TRTCQualityInfo *)localQuality remoteQuality:(NSArray<trtcqualityinfo *=""> *)remoteQuality {
// Get your local network quality
switch(localQuality.quality) {
case TRTCQuality_Unknown:
NSLog(@"SDK has not yet sensed the current network quality.");
break;
case TRTCQuality_Excellent:
NSLog(@"The current network is very good.");
break;
case TRTCQuality_Good:
NSLog(@"The current network is good.");
break;
case TRTCQuality_Poor:
NSLog(@"The current network quality barely meets the demand.");
break;
case TRTCQuality_Bad:
NSLog(@"The current network is poor, and there may be significant freezes and call delays.");
break;
case TRTCQuality_VeryBad:
NSLog(@"The current network is very poor, the communication quality cannot be guaranteed");
break;
case TRTCQuality_Down:
NSLog(@"The current network does not meet the minimum requirements.");
break;
default:
break;
}
// Get the network quality of remote users
for (TRTCQualityInfo *info in arrayList) {
NSLog(@"remote user : = %@, quality = %@", info.userId, @(info.quality));
}
}

iOSMac
// onNetworkQuality 콜백을 모니터링하여 현재 네트워크 상태 변화를 감지합니다.
void onNetworkQuality(liteav::TRTCQualityInfo local_quality,
liteav::TRTCQualityInfo* remote_quality, uint32_t remote_quality_count) {
// Get your local network quality
switch (local_quality.quality) {
case TRTCQuality_Unknown:
printf("SDK has not yet sensed the current network quality.");
break;
case TRTCQuality_Excellent:
printf("The current network is very good.");
break;
case TRTCQuality_Good:
printf("The current network is good.");
break;
case TRTCQuality_Poor:
printf("The current network quality barely meets the demand.");
break;
case TRTCQuality_Bad:
printf("The current network is poor, and there may be significant freezes and call delays.");
break;
case TRTCQuality_Vbad:
printf("The current network is very poor, the communication quality cannot be guaranteed");
break;
case TRTCQuality_Down:
printf("The current network does not meet the minimum requirements.");
break;
default:
break;
}
// Get the network quality of remote users
for (int i = 0; i < remote_quality_count; ++i) {
printf("remote user : = %s, quality = %d", remote_quality[i].userId, remote_quality[i].quality);
}
}



onStatistics 전체 네트워크 품질의 모니터링

onStatistics 통계 콜백 이벤트는 2초마다 한 번씩 발생하여 SDK 내부의 오디오/ 비디오 및 네트워크 관련 전문 기술 지표를 알립니다. 이 정보는 TRTCStatistics에 모두 나열되어 있습니다.
비디오 통계 정보: 비디오의 해상도(resolution), 프레임 속도(FPS) 및 비트레이트(bitrate) 등의 정보.
오디오 통계 정보: 오디오의 샘플링 레이트(samplerate), 채널(channel) 및 비트레이트(bitrate) 등의 정보.
네트워크 통계 정보: SDK와 클라우드 간의 한번 왕복에(SDK > Cloud > SDK) 네트워크 소요 시간(rtt), 패킷 손실률(loss), 업로드 트래픽(sentBytes) 및 다운로드 트래픽(receivedBytes) 등의 정보.
열거형
설명
appCpu
현재 앱의 CPU 사용률, 단위 (%), Android 8.0 이상에서는 지원되지 않음.
downLoss
클라우드에서 SDK로의 다운링크 패킷 손실률, 단위 (%).
해당 수치가 작을수록 좋으며, downLoss가 0%인 경우 다운링크의 네트워크 품질이 매우 좋음을 의미하며 클라우드에서 수신한 데이터 패킷이 기본적으로 손실되지 않습니다.
downLoss가 30%인 경우 클라우드에서 SDK로 전송되는 오디오 및 비디오 데이터 패킷의 30%가 전송 링크에서 손실됨을 의미합니다.
gatewayRtt
SDK에서 로컬 라우터까지의 왕복 지연 시간이며 단위 ms입니다. 해당 수치는 SDK에서 네트워크 패킷을 로컬 라우터 게이트웨이로 전송한 후, 게이트웨이에서 다시 SDK로 네트워크 패킷을 되돌려 보내는 총 소요 시간을 나타내며, 즉 "SDK > 게이트웨이 > SDK"를 거치는 네트워크 패킷의 총 소요 시간을 의미합니다.
해당 수치가 작을수록 좋습니다.gatewayRtt < 50ms인 경우 낮은 오디오 및 비디오 통화 지연을 의미하며, gatewayRtt > 200ms인 경우 높은 오디오 및 비디오 통화 지연을 의미합니다.
네트워크 유형이 셀룰러 네트워크인 경우 해당 값은 무효입니다.
localArray
로컬 오디오 및 비디오에 대한 통계 정보.
로컬에는 3개의 오디오/비디오 스트림(고화질 메인 화면, 저화질 서브 화면 및 보조 스트림 화면)이 있을 수 있으므로 로컬 오디오/비디오 통계 정보는 한 배열입니다.
receiveBytes
총 수신 바이트 수(시그널링 데이터 및 오디오/비디오 데이터 포함)의 단위는 바이트(Bytes)입니다.
remoteArray
원격 오디오 및 비디오에 대한 통계 정보.
동시에 여러 원격 사용자가 있을 수 있고, 각 원격 사용자도 동시에 여러 오디오/비디오 스트림(예: 고화질 대형 화면, 저화질 소형 화면, 보조 스트림 화면)을 가질 수 있으므로, 원격 오디오 및 비디오에 대한 통계 정보는 한 배열입니다.
rtt
SDK에서 클라우드까지의 왕복에 대한 지연 시간(단위: ms)입니다. 이 수치는 SDK에서 네트워크 패킷을 클라우드로 전송하고, 다시 클라우드에서 SDK로 회신하는 총 소요 시간을 나타내며, 즉 "SDK > 클라우드 > SDK" 경로를 거치는 네트워크 패킷의 총 소요 시간입니다.
해당 수치가 작을수록 좋습니다. rtt < 50ms인 경우 낮은 오디오 및 비디오 통화 지연을 의미하며, rtt > 200ms인 경우 높은 오디오 및 비디오 통화 지연을 의미합니다.
설명:
rtt는 "SDK > 클라우드 > SDK"의 총 소요 시간을 나타내므로 upRtt와 downRtt를 구분할 필요가 없습니다.
sendBytes
총 송신 바이트 수(시그널링 데이터 및 오디오/비디오 데이터 포함)의 단위는 바이트(Bytes)입니다.
systemCpu
현재 시스템의 CPU 사용률,단위 (%), Android 8.0 이상에서는 지원되지 않음.
upLoss
SDK에서 클라우드로까지의 업로드 패킷 손실률, 단위 (%).
해당 수치가 작을수록 좋으며, upLoss가 0%인 경우 업로드의 네트워크 품질이 매우 좋음을 의미하며, 클라우드에 업로드한 데이터 패킷이 기본적으로 손실되지 않습니다.
upLoss가 30%인 경우 SDK에서 클라우드로 전송되는 오디오 및 비디오 데이터 패킷의 30%가 전송 링크에서 손실됨을 의미합니다.
Android
iOS&Mac
Windows
@Override
public void onStatistics(TRTCStatistics statistics) {
super.onStatistics(statistics);
// appCpu 사용률
Log.d(TAG, "appCpu:" + statistics.appCpu);
// systemCpu 사용률
Log.d(TAG, "systemCpu:" + statistics.systemCpu);
// rtt SDK에서 클라우드까지의 왕복 지연 시간
Log.d(TAG, "rtt:" + statistics.rtt);
// upLoss 업로드 패킷 손실률
Log.d(TAG, "upLoss:" + statistics.upLoss);
// downLoss 다운로드 패킷 손실률
Log.d(TAG, "downLoss:" + statistics.downLoss);
// gatewayRtt 게이트웨이에서 클라우드까지의 왕복 지연 시간
Log.d(TAG, "gatewayRtt:" + statistics.gatewayRtt);
// sendBytes 전송 바이트 수
Log.d(TAG, "sendBytes:" + statistics.sendBytes);
// receiveBytes 수신 바이트 수
Log.d(TAG, "receiveBytes:" + statistics.receiveBytes);
if(statistics.localArray != null) {
for (int i = 0; i < statistics.localArray.size(); i++) {
// 로컬 비디오 너비
Log.d(TAG, "localStatistics width:" + statistics.localArray.get(i).width);
// 로컬 비디오 높이
Log.d(TAG, "localStatistics height:" + statistics.localArray.get(i).height);
// 로컬 비디오 프레임 레이트
Log.d(TAG, "localStatistics frameRate:" + statistics.localArray.get(i).frameRate);
// 로컬 비디오 비트레이트
Log.d(TAG, "localStatistics videoBitrate:" + statistics.localArray.get(i).videoBitrate);
// 로컬 오디오 비트레이트
Log.d(TAG, "localStatistics audioBitrate:" + statistics.localArray.get(i).audioBitrate);
// 로컬 오디오 장치 캡처 상태(오디오 주변 장치 상태 확인용) 0: 캡처 장치 상태 정상; 1: 장시간 무음 감지됨; 2: 음파 파손 감지됨; 3: 소리 이상 간헐 감지됨.
Log.d(TAG, "localStatistics audioCaptureState:" + statistics.localArray.get(i).audioCaptureState);
// 로컬 오디오 샘플링 레이트
Log.d(TAG, "localStatistics audioSampleRate:" + statistics.localArray.get(i).audioSampleRate);
// 로컬 스트림 유형
Log.d(TAG, "localStatistics streamType:" + statistics.localArray.get(i).streamType);
}
}
if(statistics.remoteArray != null) {
for (int i = 0; i < statistics.remoteArray.size(); i++) {
// 원격 사용자 userid
Log.d(TAG, "remoteStatistics userId:" + statistics.remoteArray.get(i).userId);
// 원격 사용자 스트림 유형
Log.d(TAG, "remoteStatistics streamType:" + statistics.remoteArray.get(i).streamType);
// 원격 비디오 너비
Log.d(TAG, "remoteStatistics width:" + statistics.remoteArray.get(i).width);
// 원격 비디오 높이
Log.d(TAG, "remoteStatistics height:" + statistics.remoteArray.get(i).height);
// 원격 비디오 프레임 레이트
Log.d(TAG, "remoteStatistics frameRate:" + statistics.remoteArray.get(i).frameRate);
// 원격 비디오 비트레이트
Log.d(TAG, "remoteStatistics videoBitrate:" + statistics.remoteArray.get(i).videoBitrate);
// 원격 비디오 정지율 단위 (%) 비디오 재생 정지율(videoBlockRate) = 비디오 재생의 누적 정지 시간(videoTotalBlockTime) / 비디오 재생의 총 시간.
Log.d(TAG, "remoteStatistics videoBlockRate:" + statistics.remoteArray.get(i).videoBlockRate);
// 비디오 재생의 누적 정지 시간, 단위 ms
Log.d(TAG, "remoteStatistics videoTotalBlockTime:" + statistics.remoteArray.get(i).videoTotalBlockTime);
// 해당 비디오 스트림의 총 패킷 손실률
// videoPacketLoss는 해당 비디오 스트림이 스트리머>클라우드>시청자와 같은 완전한 전송 경로를 거친 후 최종적으로 시청자 측에서 통계된 패킷 손실률을 나타냅니다.
// videoPacketLoss는 작을수록 좋으며, 패킷 손실률이 0이면 해당 비디오 스트림의 모든 데이터가 완전히 시청자 측에 도착했음을 의미합니다.
// downLoss == 0이지만 videoPacketLoss != 0인 경우, 해당 비디오 스트림이 클라우드>시청자 구간에서는 패킷 손실이 발생하지 않았지만 스트리머>클라우드 구간에서는 복구할 수 없는 패킷 손실이 발생했음을 의미합니다.
Log.d(TAG, "remoteStatistics videoPacketLoss:" + statistics.remoteArray.get(i).videoPacketLoss);
// 원격 오디오 비트레이트
Log.d(TAG, "remoteStatistics audioBitrate:" + statistics.remoteArray.get(i).audioBitrate);
// 원격 오디오 재생의 정지률
Log.d(TAG, "remoteStatistics audioBlockRate:" + statistics.remoteArray.get(i).audioBlockRate);
// 원격 오디오의 샘플링 레이트
Log.d(TAG, "remoteStatistics audioSampleRate:" + statistics.remoteArray.get(i).audioSampleRate);
// 원격 오디오 패킷 손실률
Log.d(TAG, "remoteStatistics audioPacketLoss:" + statistics.remoteArray.get(i).audioPacketLoss);
// 오디오 재생의 누적 정지 시간
Log.d(TAG, "remoteStatistics audioTotalBlockTime:" + statistics.remoteArray.get(i).audioTotalBlockTime);
// 재생 지연 네트워크 지터 및 패킷 순서 변동으로 인한 음성 및 영상 끊김을 방지하기 위해 RTC Engine은 재생 측에서 재생 버퍼를 관리합니다. 이 버퍼는 수신된 네트워크 데이터 패킷을 정리하는 데 사용되며, 버퍼 크기는 현재 네트워크 품질에 따라 자동으로 조정됩니다. 이 버퍼 크기를 밀리초 단위 시간으로 환산하고,즉jitterBufferDelay)입니다.
Log.d(TAG, "remoteStatistics jitterBufferDelay:" + statistics.remoteArray.get(i).jitterBufferDelay);
// 엔드투엔드 지연, 단위 ms
//point2PointDelay는 "스트리머=>클라우드=>시청자"의 지연을 나타내며, 더 정확하게 말하면 "수집=>인코딩=>네트워크 전송=>수신=>버퍼링=>디코딩=>재생" 전체 체인의 지연을 나타냅니다.
//point2PointDelay는 로컬 및 원격 SDK가 모두 8.5 이상 버전인 경우에만 적용됩니다. 원격 사용자가 8.5 이전 버전인 경우 이 값은 항상 0으로 표시되며 의미가 없습니다.
Log.d(TAG, "remoteStatistics point2PointDelay:" + statistics.remoteArray.get(i).point2PointDelay);
}
}
}

- (void)onStatistics:(TRTCStatistics *)statistics {
// appCpu 사용률
NSLog(@"appCpu: %u", statistics.appCpu);
// systemCpu 사용률
NSLog(@"systemCpu: %u", statistics.systemCpu);
// rtt SDK에서 클라우드까지의 왕복 지연 시간
NSLog(@"rtt: %d", statistics.rtt);
// upLoss 업로드 패킷 손실률
NSLog(@"upLoss: %u", statistics.upLoss);
// downLoss 다운로드 패킷 손실률
NSLog(@"downLoss: %u", statistics.downLoss);
// gatewayRtt 게이트웨이에서 클라우드까지의 왕복 지연 시간
NSLog(@"gatewayRtt: %d", statistics.gatewayRtt);
// sendBytes 전송된 바이트 수
NSLog(@"sendBytes: %llu", (unsigned long long)statistics.sentBytes);
// receiveBytes 수신 바이트 수
NSLog(@"receiveBytes: %llu", (unsigned long long)statistics.receivedBytes);

if (statistics.localStatistics != nil) {
for (int i = 0; i < statistics.localStatistics.count; i++) {
// 로컬 비디오 너비
NSLog(@"localStatistics width: %d", statistics.localStatistics[i].width);
// 로컬 비디오 높이
NSLog(@"localStatistics height: %d", statistics.localStatistics[i].height);
// 로컬 비디오 프레임 레이트
NSLog(@"localStatistics frameRate: %u", statistics.localStatistics[i].frameRate);
// 로컬 비디오 비트레이트
NSLog(@"localStatistics videoBitrate: %d", statistics.localStatistics[i].videoBitrate);
// 로컬 오디오 비트레이트
NSLog(@"localStatistics audioBitrate: %d", statistics.localStatistics[i].audioBitrate);
// 로컬 오디오 장치의 수집 상태
NSLog(@"localStatistics audioCaptureState: %d", statistics.localStatistics[i].audioCaptureState);
// 로컬 오디오 샘플링 레이트
NSLog(@"localStatistics audioSampleRate: %d", statistics.localStatistics[i].audioSampleRate);
// 로컬 스트림 유형
NSLog(@"localStatistics streamType: %ld", (long)statistics.localStatistics[i].streamType);
}
}

if (statistics.remoteStatistics != nil) {
for (int i = 0; i < statistics.remoteStatistics.count; i++) {
// 원격 사용자 userid
NSLog(@"remoteStatistics userId: %@", statistics.remoteStatistics[i].userId);
// 원격 사용자 스트림 유형
NSLog(@"remoteStatistics streamType: %ld", (long)statistics.remoteStatistics[i].streamType);
// 원격 비디오 너비
NSLog(@"remoteStatistics width: %d", statistics.remoteStatistics[i].width);
// 원격 비디오 높이
NSLog(@"remoteStatistics height: %d", statistics.remoteStatistics[i].height);
// 원격 비디오 프레임 레이트
NSLog(@"remoteStatistics frameRate: %u", statistics.remoteStatistics[i].frameRate);
// 원격 비디오 비트레이트
NSLog(@"remoteStatistics videoBitrate: %d", statistics.remoteStatistics[i].videoBitrate);
// 원격 비디오 정지률
NSLog(@"remoteStatistics videoBlockRate: %u", statistics.remoteStatistics[i].videoBlockRate);
// 비디오 재생의 누적 정지 시간
NSLog(@"remoteStatistics videoTotalBlockTime: %d", statistics.remoteStatistics[i].videoTotalBlockTime);
// 해당 비디오 스트림의 총 패킷 손실률
NSLog(@"remoteStatistics videoPacketLoss: %u", statistics.remoteStatistics[i].videoPacketLoss);
// 원격 오디오 비트레이트
NSLog(@"remoteStatistics audioBitrate: %d", statistics.remoteStatistics[i].audioBitrate);
// 원격 오디오 재생의 정지률
NSLog(@"remoteStatistics audioBlockRate: %u", statistics.remoteStatistics[i].audioBlockRate);
// 원격 오디오의 샘플링 레이트
NSLog(@"remoteStatistics audioSampleRate: %d", statistics.remoteStatistics[i].audioSampleRate);
// 원격 오디오 패킷 손실률
NSLog(@"remoteStatistics audioPacketLoss: %u", statistics.remoteStatistics[i].audioPacketLoss);
// 오디오 재생의 누적 정지 시간
NSLog(@"remoteStatistics audioTotalBlockTime: %d", statistics.remoteStatistics[i].audioTotalBlockTime);
// 재생 지연
NSLog(@"remoteStatistics jitterBufferDelay: %d", statistics.remoteStatistics[i].jitterBufferDelay);
// 엔드투엔드 지연
NSLog(@"remoteStatistics point2PointDelay: %d", statistics.remoteStatistics[i].point2PointDelay);
}
}

}

void onStatistics(const TRTCStatistics& statistics) {
// appCpu 사용률
printf("appCpu: %f\n", statistics.appCpu);
// systemCpu 사용률
printf("systemCpu: %f\n", statistics.systemCpu);
// rtt SDK에서 클라우드까지의 왕복 지연 시간
printf("rtt: %d\n", statistics.rtt);
// upLoss 업로드 패킷 손실률
printf("upLoss: %f\n", statistics.upLoss);
// downLoss 다운로드 패킷 손실률
printf("downLoss: %f\n", statistics.downLoss);
// gatewayRtt 게이트웨이에서 클라우드까지의 왕복 지연 시간
printf("gatewayRtt: %d\n", statistics.gatewayRtt);
// sentBytes 전송된 바이트 수
printf("sentBytes: %lld\n", statistics.sentBytes);
// receiveBytes 수신 바이트 수
printf("receivedBytes: %lld\n", statistics.receivedBytes);

//for (const auto& localStat : statistics.localStatisticsArray) {
if (statistics.localStatisticsArray != nullptr && statistics.localStatisticsArraySize != 0)
{
for (int i = 0; i < statistics.localStatisticsArraySize; i++)
{
// 로컬 비디오 너비
printf("localStatistics width: %d\n", statistics.localStatisticsArray[i].width);
// 로컬 비디오 높이
printf("localStatistics height: %d\n", statistics.localStatisticsArray[i].height);
// 로컬 비디오 프레임 레이트
printf("localStatistics frameRate: %f\n", statistics.localStatisticsArray[i].frameRate);
// 로컬 비디오 비트레이트
printf("localStatistics videoBitrate: %d\n", statistics.localStatisticsArray[i].videoBitrate);
// 로컬 오디오 비트레이트
printf("localStatistics audioBitrate: %d\n", statistics.localStatisticsArray[i].audioBitrate);
// 로컬 오디오 장치의 수집 상태
printf("localStatistics audioCaptureState: %d\n", statistics.localStatisticsArray[i].audioCaptureState);
// 로컬 오디오 샘플링 레이트
printf("localStatistics audioSampleRate: %d\n", statistics.localStatisticsArray[i].audioSampleRate);
// 로컬 스트림 유형
printf("localStatistics streamType: %d\n", statistics.localStatisticsArray[i].streamType);
}
}

//for (const auto& remoteStat : statistics.remoteStatisticsArray) {
if (statistics.remoteStatisticsArray != nullptr && statistics.remoteStatisticsArraySize != 0)
{
for (int i = 0; i < statistics.remoteStatisticsArraySize; i++)
{
// 원격 사용자 userid
printf("remoteStatistics userId: %s\n", statistics.remoteStatisticsArray[i].userId);
// 원격 사용자 스트림 유형
printf("remoteStatistics streamType: %d\n", statistics.remoteStatisticsArray[i].streamType);
// 원격 비디오 너비
printf("remoteStatistics width: %d\n", statistics.remoteStatisticsArray[i].width);
// 원격 비디오 높이
printf("remoteStatistics height: %d\n", statistics.remoteStatisticsArray[i].height);
// 원격 비디오 프레임 레이트
printf("remoteStatistics frameRate: %f\n", statistics.remoteStatisticsArray[i].frameRate);
// 원격 비디오 비트레이트
printf("remoteStatistics videoBitrate: %d\n", statistics.remoteStatisticsArray[i].videoBitrate);
// 원격 비디오 정지률
printf("remoteStatistics videoBlockRate: %f\n", statistics.remoteStatisticsArray[i].videoBlockRate);
// 비디오 재생의 누적 정지 시간
printf("remoteStatistics videoTotalBlockTime: %d\n", statistics.remoteStatisticsArray[i].videoTotalBlockTime);
// 해당 비디오 스트림의 총 패킷 손실률
printf("remoteStatistics videoPacketLoss: %f\n", statistics.remoteStatisticsArray[i].videoPacketLoss);
// 원격 오디오 비트레이트
printf("remoteStatistics audioBitrate: %d\n", statistics.remoteStatisticsArray[i].audioBitrate);
// 원격 오디오 재생의 정지률
printf("remoteStatistics audioBlockRate: %f\n", statistics.remoteStatisticsArray[i].audioBlockRate);
// 원격 오디오의 샘플링 레이트
printf("remoteStatistics audioSampleRate: %d\n", statistics.remoteStatisticsArray[i].audioSampleRate);
// 원격 오디오 패킷 손실률
printf("remoteStatistics audioPacketLoss: %f\n", statistics.remoteStatisticsArray[i].audioPacketLoss);
// 오디오 재생의 누적 정지 시간
printf("remoteStatistics audioTotalBlockTime: %d\n", statistics.remoteStatisticsArray[i].audioTotalBlockTime);
// 재생 지연
printf("remoteStatistics jitterBufferDelay: %d\n", statistics.remoteStatisticsArray[i].jitterBufferDelay);
// 엔드투엔드 지연
printf("remoteStatistics point2PointDelay: %d\n", statistics.remoteStatisticsArray[i].point2PointDelay);
}
}
}


통화 중의 연결 모니터링

사용자는 통화 중에 네트워크 변화를 인지할 뿐만 아니라 현재 SDK와 백엔드의 연결 상태를 파악해야 합니다. 이를 통해 사용자는 현재 네트워크가 조정되었는지, 정상적으로 통화할 수 있는지를 더 정확하게 판단할 수 있습니다.



콜백 인터페이스
인터페이스에 대한 설명
onConnectionLost
SDK와 클라우드 간의 연결이 끊어졌습니다.
onTryToReconnect
SDK가 클라우드에 재연결을 시도 중입니다.
onConnectionRecovery
SDK와 클라우드와의 연결이 복구되었습니다.

연결 재설정 로직

사용자가 연결이 끊긴 경우, SDK는 자동으로 재연결을 지원합니다(30분 동안 재연결에 성공하지 못하면 자동으로 방을 나가고 -3301 오류 코드를 반환함). 연결 과정에서의 구체적인 연결 상태 및 처리 로직은 아래와 같습니다. 아래 그림은 사용자 Userid1이 채널에 입장한 후 연결이 끊어지고 다시 방에 입장하는 과정에서 수신한 리스너 콜백 이벤트를 보여줍니다.



구체적인 설명:
T1:사용자 측에서 enterRoom 인터페이스를 호출하여 방 입장 요청을 시작합니다.
T2:사용자 Userid1이 onEnterRoom 콜백을 수신하고, Userid2가 Userid1의 존재를 인지하여 약 300ms 후에 Userid2가 onRemoteUserEnterRoom 콜백을 수신합니다.
T3:Userid1 클라이언트가 네트워크 문제로 연결이 끊어지면 SDK가 방에 다시 입장하려고 시도합니다.
T4:Userid1이 8초 연속으로 서버에 연결되지 않으면 Userid1은 onConnectionLost 연결 끊김 콜백을 받습니다.
T5:Userid1이 3초 간격으로 서버에 연결되지 않으면 Userid1은 onTryToReconnect 재시도 콜백을 받습니다.
T6:Userid1이 24초마다 onTryToReconnect 재시도 콜백을 받습니다.
T7:Userid2는 Userid1의 연결 끊김 알림을 받고 90초 지난 후에 SDK에서 원격 사용자 Userid1의 연결 끊김을 판단되면 Userid2는 onRemoteUserLeaveRoom 콜백을 받습니다.
T8:Userid1이 연결이 끊긴 동안 언제든지 재연결에 성공되면 Userid1은 onConnectionRecovery 복구 콜백을 받습니다.
Android
iOS&Mac
Windows
@Override
public void onConnectionLost() {
// 연결 끊김
Log.d(TAG, "onConnectionLost");
}

@Override
public void onTryToReconnect() {
// 재연결 시도
Log.d(TAG, "onTryToReconnect");
}

@Override
public void onConnectionRecovery() {
// 재연결 성공
Log.d(TAG, "onConnectionRecovery");
}
- (void)onConnectionLost {
// 연결 끊김
NSLog(@"onConnectionLost");
}

- (void)onTryToReconnect {
// 재연결 시도
NSLog(@"onTryToReconnect");
}

- (void)onConnectionRecovery {
// 재연결 성공
NSLog(@"onConnectionRecovery");
}


void onConnectionLost() {
// 연결 끊김
printf("onConnectionLost\n");
}

void onTryToReconnect() {
// 재연결 시도
printf("onTryToReconnect\n");
}

void onConnectionRecovery() {
// 재연결 성공
printf("onConnectionRecovery\n");
}