@@ -12,6 +12,8 @@ export interface ProtocolStats {
1212 count : number ;
1313}
1414
15+ const TEST_DURATION = 10000 ;
16+
1517export class ConnectionProtocolCheck extends Checker {
1618 private bestStats ?: ProtocolStats ;
1719
@@ -24,43 +26,40 @@ export class ConnectionProtocolCheck extends Checker {
2426 const tcpStats = await this . checkConnectionProtocol ( 'tcp' ) ;
2527 this . bestStats = udpStats ;
2628 // udp should is the better protocol typically. however, we'd prefer TCP when either of these conditions are true:
27- // 1. the bandwidth limitation is worse on UDP by 500ms (10% of the test duration)
29+ // 1. the bandwidth limitation is worse on UDP by 500ms
2830 // 2. the packet loss is higher on UDP by 1%
2931 if (
3032 udpStats . qualityLimitationDurations . bandwidth -
3133 tcpStats . qualityLimitationDurations . bandwidth >
3234 0.5 ||
3335 ( udpStats . packetsLost - tcpStats . packetsLost ) / udpStats . packetsSent > 0.01
3436 ) {
35- this . appendMessage ( 'best connection quality via TCP ' ) ;
37+ this . appendMessage ( 'best connection quality via tcp ' ) ;
3638 this . bestStats = tcpStats ;
3739 } else {
38- this . appendMessage ( 'best connection quality via UDP ' ) ;
40+ this . appendMessage ( 'best connection quality via udp ' ) ;
3941 }
4042
43+ const stats = this . bestStats ;
4144 this . appendMessage (
42- `upstream bitrate: ${ ( this . bestStats . bitrateTotal / this . bestStats . count / 1000 / 1000 ) . toFixed ( 2 ) } mbps` ,
43- ) ;
44- this . appendMessage (
45- `RTT: ${ ( ( this . bestStats . rttTotal / this . bestStats . count ) * 1000 ) . toFixed ( 2 ) } ms` ,
46- ) ;
47- this . appendMessage (
48- `jitter: ${ ( ( this . bestStats . jitterTotal / this . bestStats . count ) * 1000 ) . toFixed ( 2 ) } ms` ,
45+ `upstream bitrate: ${ ( stats . bitrateTotal / stats . count / 1000 / 1000 ) . toFixed ( 2 ) } mbps` ,
4946 ) ;
47+ this . appendMessage ( `RTT: ${ ( ( stats . rttTotal / stats . count ) * 1000 ) . toFixed ( 2 ) } ms` ) ;
48+ this . appendMessage ( `jitter: ${ ( ( stats . jitterTotal / stats . count ) * 1000 ) . toFixed ( 2 ) } ms` ) ;
5049
51- if ( this . bestStats . packetsLost > 0 ) {
52- this . appendMessage (
53- `packets lost: ${ ( ( this . bestStats . packetsLost / this . bestStats . packetsSent ) * 100 ) . toFixed ( 2 ) } %` ,
50+ if ( stats . packetsLost > 0 ) {
51+ this . appendWarning (
52+ `packets lost: ${ ( ( stats . packetsLost / stats . packetsSent ) * 100 ) . toFixed ( 2 ) } %` ,
5453 ) ;
5554 }
56- if ( this . bestStats . qualityLimitationDurations . bandwidth > 0 ) {
55+ if ( stats . qualityLimitationDurations . bandwidth > 1 ) {
5756 this . appendWarning (
58- `bandwidth limited ${ ( ( this . bestStats . qualityLimitationDurations . bandwidth / 5 ) * 100 ) . toFixed ( 2 ) } %` ,
57+ `bandwidth limited ${ ( ( stats . qualityLimitationDurations . bandwidth / ( TEST_DURATION / 1000 ) ) * 100 ) . toFixed ( 2 ) } %` ,
5958 ) ;
6059 }
61- if ( this . bestStats . qualityLimitationDurations . cpu > 0 ) {
60+ if ( stats . qualityLimitationDurations . cpu > 0 ) {
6261 this . appendWarning (
63- `cpu limited ${ ( ( this . bestStats . qualityLimitationDurations . cpu / 5 ) * 100 ) . toFixed ( 2 ) } %` ,
62+ `cpu limited ${ ( ( stats . qualityLimitationDurations . cpu / ( TEST_DURATION / 1000 ) ) * 100 ) . toFixed ( 2 ) } %` ,
6463 ) ;
6564 }
6665 }
@@ -72,10 +71,11 @@ export class ConnectionProtocolCheck extends Checker {
7271 }
7372
7473 private async checkConnectionProtocol ( protocol : 'tcp' | 'udp' ) : Promise < ProtocolStats > {
75- this . appendMessage ( `connecting via ${ protocol } ` ) ;
7674 await this . connect ( ) ;
7775 if ( protocol === 'tcp' ) {
7876 await this . switchProtocol ( 'tcp' ) ;
77+ } else {
78+ await this . switchProtocol ( 'udp' ) ;
7979 }
8080
8181 // create a canvas with animated content
@@ -103,8 +103,12 @@ export class ConnectionProtocolCheck extends Checker {
103103 // publish to room
104104 const pub = await this . room . localParticipant . publishTrack ( videoTrack , {
105105 simulcast : false ,
106+ degradationPreference : 'maintain-resolution' ,
107+ videoEncoding : {
108+ maxBitrate : 2000000 ,
109+ } ,
106110 } ) ;
107- const track = pub . track ! ;
111+ const track = pub ! . track ! ;
108112
109113 const protocolStats : ProtocolStats = {
110114 protocol,
@@ -124,7 +128,6 @@ export class ConnectionProtocolCheck extends Checker {
124128 protocolStats . packetsSent = stat . packetsSent ;
125129 protocolStats . qualityLimitationDurations = stat . qualityLimitationDurations ;
126130 protocolStats . bitrateTotal += stat . targetBitrate ;
127-
128131 protocolStats . count ++ ;
129132 } else if ( stat . type === 'remote-inbound-rtp' ) {
130133 protocolStats . packetsLost = stat . packetsLost ;
@@ -135,10 +138,11 @@ export class ConnectionProtocolCheck extends Checker {
135138 } , 1000 ) ;
136139
137140 // wait a bit to gather stats
138- await new Promise ( ( resolve ) => setTimeout ( resolve , 5000 ) ) ;
141+ await new Promise ( ( resolve ) => setTimeout ( resolve , TEST_DURATION ) ) ;
139142 clearInterval ( interval ) ;
140143
141144 videoTrack . stop ( ) ;
145+ canvas . remove ( ) ;
142146 await this . disconnect ( ) ;
143147 return protocolStats ;
144148 }
0 commit comments