Client
moqt.Client manages client-side operations for the MoQ protocol. It establishes and maintains sessions, handling the lifecycle.
Overview
func main() {
// Create a new client
client := moqt.Client{
// Set client options here
}
// Dial and establish a session with the server
sess, err := client.Dial(context.Background(), "https://[addr]:[port]/[path]", nil)
if err != nil {
log.Fatalf("Failed to dial: %v", err)
}
defer sess.CloseWithError(moqt.NoErrorCode, "Client shutting down")
// Use the session (e.g., subscribe to tracks, receive announcements)
// Gracefully shut down the client when done
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := client.Shutdown(ctx); err != nil {
log.Printf("Client shutdown error: %v", err)
}
}Initialize a Client
There is no dedicated function (such as a constructor) for initializing a client. Users define the struct directly and assign values to its fields as needed.
client := moqt.Client{
// Set client options here
}Configuration
The following table describes the public fields of the moqt.Client struct:
| Field | Type | Description |
|---|---|---|
TLSConfig | *tls.Config | TLS configuration for secure connections |
QUICConfig | *quic.Config | QUIC protocol configuration |
Config | *moqt.Config | MOQ protocol configuration |
DialQUICFunc | quic.DialAddrFunc | Function to dial QUIC connection |
DialWebTransportFunc | webtransport.DialAddrFunc | Function to dial WebTransport connection |
Logger | *slog.Logger | Logger for client events and errors |
quic-go/quic-go is used internally as the default QUIC implementation when relevant fields which is set for customization are not set or nil.
To use a custom QUIC implementation, you need to provide your own implementation of the quic.DialAddrFunc. (moqt.Client).DialQUICFunc field is set, it is used to dial QUIC connections instead of the default implementation.
type Client struct {
// ...
DialQUICFunc quic.DialAddrFunc
// ...
}quic-go/webtransport-go is used internally as the default WebTransport implementation when relevant fields which is set for customization are not set or nil.
To use a custom WebTransport implementation, you need to provide your own implementation of the webtransport.DialAddrFunc. (moqt.Client).DialWebTransportFunc field is set, it is used to dial WebTransport connections instead of the default implementation.
type Client struct {
// ...
DialWebTransportFunc webtransport.DialAddrFunc
// ...
}Dial and Establish Session
Clients can initiate a QUIC connection and establish a MOQ session with a server using the (*moqt.Client).Dial method.
var mux *TrackMux
sess, err := client.Dial(ctx, "https://[addr]:[port]/[path]", mux)
if err != nil {
// Handle error
return
}
// Handle sessionNote: Nil TrackMux
When mux is set to nil, the moqt.DefaultTrackMux will be used by default.
Ensure that the mux is properly configured for your use case to avoid unexpected behavior.
Shutting Down a Client
Clients can shut down in two ways: immediate or graceful.
Immediate Shutdown
(moqt.Client).Close method forcefully terminates all sessions and releases resources. Use cautiously as it may interrupt operations.
client.Close() // Immediate shutdownGraceful Shutdown
(moqt.Client).Shutdown method waits for sessions to close naturally, or forces termination on timeout.
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
err := client.Shutdown(ctx)
if err != nil {
// Handle forced termination
}Note: GOAWAY message
The current implementation does not send a GOAWAY message during shutdown. Immediate session closure occurs when the context is canceled. This will be updated once the GOAWAY message specification is finalized.
đ Future Work
- Implement GOAWAY message: (#XXX)