NWConnectionGroup w/QUIC Best Practices

Hello. Wanted to ask about the right way, or the intended way to leverage NWConnectionGroup for a QUIC based streaming solution.

The use case is, we are making a request from the client in order to play a movie, and we want to send as much video frames as possible (and as fast as possible) from the streaming server, which also uses the Network framework.

Our understanding is, NWConnectionGroup will open a QUIC tunnel between both parties so we can multiplex different streams to the client and we are already doing that.

We see a throughput of approx. 20-35MB/s (client device is an iPad and server is an M2 macbook pro running a server app) and we would like to understand if we can improve these results way more.

For example:

1.- Is it a good practice to create a second tunnel (NWConnectionGroup), or is not needed here?. We tried that, but the second one is also coming with id 0 on the metadata object, just as the first group we instantiated, not sure why this is the case.

2.- We are using a pool of several NWConnection (initialized with the group object) already instantiated, that way we send a video buffer in chunks as a stream on each connection. We use one connection for a buffer and when we need to send another buffer we use a different NWConnection pulled from the pool.

We maybe just want a confirmation/validation of what we are doing, or to see if we are missing something on our implementation...

Thanks in advance.

Our understanding is, NWConnectionGroup will open a QUIC tunnel between both parties so we can multiplex different streams to the client

Correct.

and we are already doing that.

Cool.

Is it a good practice to create a second tunnel (NWConnectionGroup) … ?

No.

The one thing I recommend you explore is QUIC datagrams. In most video streaming situations you don’t want reliable delivery, because if a packet gets dropped then, by the time its gets retransmitted, the video data will be too late to be useful. Hence, in the old school world it’s common use use TCP for command and control and UDP for the video frames.

With QUIC you can do this all through a single tunnel (connection group). In both cases you use the init(from:to:using:) initialiser to create your stream, but for a datagram stream you pass in an NWParameters value with the isDatagram property set.

IMPORTANT You can only create a single datastream connection per connection group.

The docs are rather thin on the ground so I recommend you read the doc comments in <Networkquic_options.h>. Oh, and RFC 9221.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

We really appreciate this recommendation, regarding the use of QUIC Datagrams and we just put it in the queue for the next POC, thank you this was extremely helpful.

Now, since we are constructing a document with the actual POC implementation we have (just because it is a business requirement), the one I just described previously, we would like to report/ask about an strange behavior in which the throughput starts really well approx. 62MB/s or higher but after sometime 30s or so it goes to approx. 1-2MB/s or less, then after sometime it recovers again but can also drops just as the first time and then the pattern repeats on and on. I'm two meters away from my 6GHz wifi router when I run the tests.

Above is basically the server sending the packets, that FLAT behavior at the right is what we do not understand.

We would really appreciate some diagnostic on this issue and happy to provide more details if needed.

Thanks in advance.

NWConnectionGroup w/QUIC Best Practices
 
 
Q