imquic examples

June 9, 2026 ยท View on GitHub

This folder contains a set of examples aimed at showcasing how you can integrate imquic in applications for different use cases. Notice that they're meant as simple demo examples, and are not strictly speaking representative of the coding style you should adhere to, or indicative of the expected performance of the library.

There are a few different client/server examples showing how you can use imquic for:

  • generic QUIC applications (raw QUIC and/or WebTransport);
  • native RTP over QUIC (RoQ) support;
  • native Media over QUIC (MoQ) support.

You can choose which examples to build by passing arguments to the ./configure script.

All demos allow you to create QLOG files, assuming QLOG support is available in the library. You can enable it passing -Q <path>, where <path> will need to be the path to a valid folder: filenames will be automatically generated by the library (see the documentation for details). By default, this will serialize QLOG to contained JSON files, but for HTTP/3, RoQ and Moq you can also create sequential JSON files by passing -J. Notice that, even when QLOG is enabled, the examples won't save anything by default: you're required to specify what you want to trace using one or multiple calls to -l <protocol> (where <protocol> can be quic, http3, roq or moq; -l quic -l moq will trace both QUIC and MoQ in the MoQ examples, for instance).

Echo examples

To build the client/server echo examples, pass --enable-echo-examples to the ./configure script. This will build two command line applications, namely:

  • imquic-echo-server, a basic QUIC/WebTransport echo server;
  • imquic-echo-client, a basic QUIC/WebTransport echo client.

Both provide a few configuration options: pass -h or --help for more information.

This example launches a raw QUIC server (since -q is passed), negotiating the doq ALPN, listening on port 9000 (-p), using the provided certificate (-c) and key (-k), and saving the shared TLS secrets to the provided SSLKEYLOGFILE (-s, e.g., for live debugging of the QUIC traffic via Wireshark):

./examples/imquic-echo-server -q -a doq -p 9000 -c ../localhost.crt -k ../localhost.key -s ../key_log.log

This has the echo client connect to that server (-r provides the remote host, -R the remote port):

./examples/imquic-echo-client -q -a doq -r 127.0.0.1 -R 9000

This other example launches a WebTransport server (since -w is passed) instead:

./examples/imquic-echo-server -w -p 9000 -c ../localhost.crt -k ../localhost.key

This has the echo client connect to that server:

./examples/imquic-echo-client -w -r 127.0.0.1 -R 9000

In both cases, the client will then send a single ciao buffer on a bidirectional STREAM that the server will echo back. Both client and server can be configured to offer both raw QUIC and WebTransport at the same time.

RTP Over QUIC (RoQ) examples

To build the RTP Over QUIC (RoQ) examples, pass --enable-roq-examples to the ./configure script. This will build two command line applications, namely:

  • imquic-roq-sender, a basic RoQ sender, that will listen for RTP packets on some UDP ports, and restream them via QUIC.
  • imquic-roq-receiver, a basic RoQ receiver, that can print the flow ID and RTP headers of the incoming packets, and/or echo packets back;

Both demos can act as either a server or a client, and provide a few configuration options: pass -h or --help for more information.

This launches the RoQ receiver as a server (-o is omitted, so the default behaviour applies) on port 9000, using the provided certificate; raw QUIC is used (-q), but unlike before the ALPN is omitted, since it will automatically be set by the RoQ stack in the library:

./examples/imquic-roq-receiver -q -p 9000 -c ../localhost.crt -k ../localhost.key

Since no other parameter is provided, the default behaviour is just to print some detail about incoming packets. To not show such information, the -Z or --quiet flag can be passed. The RoQ receiver can also be configured to echo packets back to the client via -e or --echo. This launches the same RoQ server as before, but in quiet (-Z) and echo (-e) mode and on WebTransport too (-w):

./examples/imquic-roq-receiver -w -q -p 9000 -Z -e -c ../localhost.crt -k ../localhost.key

This instead launches the RoQ sender as a client (-o) to connect to that server (whether in echo mode or not), waiting for audio RTP packets on port 15002 (whose flow ID on RoQ will be 0) and for video RTP packets on port 15004 (whose flow ID on RoQ will be 1), and using a separate STREAM for each RTP packet:

./examples/imquic-roq-sender -o -q -a 15002 -A 0 -v 15004 -V 1 -r 127.0.0.1 -R 9000 -m streams

Sending RTP traffic to those ports (e.g., from GStreamer, FFmpeg, Janus RTP forwarders or others), will have the RoQ sender send them to the RoQ receiver.

Since both demos can act as both client and server, it's possible to reverse the QUIC roles of this demo. When a sender acts as a server, it will relay RTP packets via RoQ to all the receiver clients that connect.

Media Over QUIC (MoQ) examples

To build the Media Over QUIC (MoQ) examples, pass --enable-moq-examples to the ./configure script. This will build a few command line applications, namely:

  • imquic-moq-pob, a basic MoQ publisher (basically a clone on moq-clock in moq-rs);
  • imquic-moq-sub, a basic MoQ subscriber (with support for a few different kinds of media);
  • imquic-moq-loc-send, a MoQ publisher that can publish live audio/video using LOC;
  • imquic-moq-loc-recv, a MoQ subscriber that can subscribe to (and render) live audio/video using LOC;
  • imquic-moq-interop-test, a client-side implementation of the MoQ Interop Runner;
  • imquic-moq-relay, a basic MoQ relay.

All provide a few configuration options: pass -h or --help for more information.

Having a relay available is a prerequisite for testing the client demos. The imquic-moq-relay application is a basic (and not very performant) relay implementation with support for most of the MoQ features. This launches a MoQ relay that can be reached both via raw QUIC and WebTransport (-q -w), and that only accepts connections negotiating version -07 of the draft (-M):

./examples/imquic-moq-relay -p 9000 -c ../localhost.crt -k ../localhost.key -q -w -M 7

Assuming a relay (imquic-moq-relay or others) is listening on that address, this creates a MoQ publisher using WebTransport (-w) that publishes the current time to the clock namespace and now track; since -M is not provided, support for multiple versions of MoQ is offered:

./examples/imquic-moq-pub -r 127.0.0.1 -R 9000 -w -n clock -N now -w

A MoQ subscriber for that namespace/track (with -t text to tell the application to interpret the objects as text) using raw QUIC (-q) can be run as following:

./examples/imquic-moq-sub -r 127.0.0.1 -R 9000 -q -n clock -N now -t text

Assuming a relay is available at that address and that a moq-encoder-player instance is publishing audio and video, this creates a MoQ subscriber (on WebTransport) to both tracks that prints the LOC header (-t loc) of each incoming object:

./examples/imquic-moq-sub -r 127.0.0.1 -R 4433 -w -H /moq -n vc -N 12345678-audio -N 12345678-video -A secret -t loc -w

imquic-moq-sub also supports FETCH to obtain objects from a relay, both in standalone and (assuming v08 of the draft is used) joining mode. You enable FETCH by specifying the order you want using -f: by default this enables standalone fetch, but if you want a joining one (meaning a SUBSCRIBE is sent too) you also need to specify the preceding group offset via the -j property. This is an example of subscribing to the current time with a joining fetch that's just interested in all objects from the latest group (-j 0):

./examples/imquic-moq-sub -r 127.0.0.1 -R 9000 -w -n clock -N now -t text -M 8 -f ascending -j 0

Live audio and/or video can also be tested using imquic-moq-loc-send (publisher) and imquic-moq-loc-recv (subscriber), both of which use LOC as a streaming format. This creates a publisher that uses the vc namespace (-n), and then captures a microphone (that will be published to the trackname specified with -A) and a webcam (that will be published to the trackname specified with -V`):

./examples/imquic-moq-loc-send -r 127.0.0.1 -R 9000 -w -q -n vc -A 12345678-audio -V 12345678-video

A subscriber for those streams can be created this way instead:

./examples/imquic-moq-loc-recv -r 127.0.0.1 -R 9000 -w -q -n vc -A 12345678-audio -V 12345678-video

By default, the receiver will print metadata associated to all objects it receives: to print the content of the LOC properties, -P can be passed. To hide all metadata and not make the logs too verbose, you can make them quiet using -Z.

imquic-moq-interop-test implements the client side of the MoQ Interop Runner framework. Its interface is standardized: you can find more details here.