0.3.5-alpha.4
This commit is contained in:
@@ -1,9 +1,25 @@
|
||||
<!-- file: crates/common/game-realtime-webtransport-lib/USAGE.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Utilisation de game-realtime-webtransport-lib
|
||||
|
||||
Ce guide décrit le chemin natif fiable actuellement exposé par `game-realtime-webtransport-lib`. Il ne décrit ni gameplay, ni protocole wire métier, ni datagrams.
|
||||
Ce guide décrit le chemin natif fiable exposé par `game-realtime-webtransport-lib`. Il ne décrit ni gameplay, ni protocole wire métier, ni datagrams.
|
||||
|
||||
## Configuration transport
|
||||
|
||||
`WebTransportConfig` porte les limites et deadlines du chemin fiable. La configuration par défaut garde une limite de 1 MiB par message et des deadlines bornées pour connexion, stream primaire et send.
|
||||
|
||||
Exemple de configuration plus stricte :
|
||||
|
||||
```rust
|
||||
let transport = game_realtime_webtransport_lib::WebTransportConfig::default()
|
||||
.with_max_message_size(256 * 1024)
|
||||
.with_connect_timeout(std::time::Duration::from_secs(5))
|
||||
.with_primary_stream_timeout(std::time::Duration::from_secs(2))
|
||||
.with_send_timeout(std::time::Duration::from_secs(2));
|
||||
```
|
||||
|
||||
La validation effective se fait lors du bind serveur ou de la connexion client. Une limite nulle, une limite non représentable en `u32` ou une deadline nulle est rejetée comme `InvalidConfiguration`.
|
||||
|
||||
## Serveur natif
|
||||
|
||||
@@ -17,7 +33,8 @@ let identity = match game_realtime_webtransport_lib::WebTransportServerIdentity:
|
||||
let config = game_realtime_webtransport_lib::WebTransportServerConfig::new(
|
||||
std::net::SocketAddr::from(([127, 0, 0, 1], 4433)),
|
||||
identity,
|
||||
);
|
||||
)
|
||||
.with_transport_config(transport);
|
||||
let mut listener = match game_realtime_webtransport_lib::WebTransportListener::bind(config) {
|
||||
Ok(value) => value,
|
||||
Err(error) => return Err(error),
|
||||
@@ -32,6 +49,8 @@ let connection = match session.accept_primary_connection().await {
|
||||
};
|
||||
```
|
||||
|
||||
L'attente du prochain client dans `listener.accept()` n'a pas de timeout périodique. Une fois une requête WebTransport surfacée, sa réponse finale utilise la deadline de connexion configurée.
|
||||
|
||||
`open_primary_connection()` écrit l'en-tête WebTransport requis pour identifier le stream avant de retourner. Le serveur peut donc attendre `accept_primary_connection()` puis commencer les échanges applicatifs ; aucune frame artificielle n'est nécessaire pour rendre le stream visible.
|
||||
|
||||
## Client natif
|
||||
@@ -43,7 +62,7 @@ let config = match game_realtime_webtransport_lib::WebTransportClientConfig::new
|
||||
"https://127.0.0.1:4433/game",
|
||||
certificate_hash,
|
||||
) {
|
||||
Ok(value) => value,
|
||||
Ok(value) => value.with_transport_config(transport),
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
let session = match game_realtime_webtransport_lib::connect(&config).await {
|
||||
@@ -60,7 +79,7 @@ Le pinning est obligatoire dans cette API native ; il n'existe pas de variante q
|
||||
|
||||
## Contrat realtime
|
||||
|
||||
Une fois le stream primaire sélectionné, utiliser uniquement les traits de `game-realtime-transport-lib` :
|
||||
Une fois le stream primaire sélectionné, utiliser les traits de `game-realtime-transport-lib` pour le chemin fiable normal :
|
||||
|
||||
```rust
|
||||
let (mut sender, mut receiver) = game_realtime_transport_lib::RealtimeConnection::split(connection);
|
||||
@@ -82,8 +101,30 @@ if let Err(error) = game_realtime_transport_lib::RealtimeSender::close(&mut send
|
||||
|
||||
Le backend encode chaque `TransportMessage` sous la forme `u32` big-endian + payload. Le consommateur ne doit pas reproduire ce framing lui-même.
|
||||
|
||||
## Fermeture actuelle
|
||||
La flow-control QUIC est respectée naturellement par l'écriture asynchrone. Un send qui dépasse sa deadline est considéré terminal : le stream est reset et le même sender ne doit pas être réutilisé.
|
||||
|
||||
## Fermeture et abort
|
||||
|
||||
`RealtimeSender::close()` termine proprement la direction d'émission du stream primaire. Le pair observe ensuite `TransportReceive::Closed` lorsqu'il atteint le FIN après les messages déjà écrits.
|
||||
|
||||
La fermeture de session complète, les resets, les aborts, les timeouts et les cas d'annulation appartiennent à la tranche de robustesse suivante et ne doivent pas être simulés par le consommateur.
|
||||
Pour abandonner explicitement une direction WebTransport :
|
||||
|
||||
```rust
|
||||
if let Err(error) = sender.abort(42) {
|
||||
return Err(error);
|
||||
}
|
||||
```
|
||||
|
||||
ou côté réception :
|
||||
|
||||
```rust
|
||||
if let Err(error) = receiver.abort(43) {
|
||||
return Err(error);
|
||||
}
|
||||
```
|
||||
|
||||
Ces deux méthodes sont backend-spécifiques : elles ne sont pas ajoutées au contrat commun car WebSocket n'expose pas la même primitive QUIC de reset/stop.
|
||||
|
||||
Dropper un sender actif ou annuler une future `send()` en cours provoque un reset explicite. Dropper un receiver actif provoque un stop explicite. Cela évite qu'une cancellation d'écriture partielle soit interprétée comme une fermeture propre ou qu'une frame suivante reprenne au mauvais offset.
|
||||
|
||||
Une future `receive()` peut en revanche être annulée puis relancée : le backend conserve l'état partiel du header/payload et reprend le framing à l'octet correct.
|
||||
|
||||
Reference in New Issue
Block a user