Skip to main content

webtransport 0.1.0 copy "webtransport: ^0.1.0" to clipboard
webtransport: ^0.1.0 copied to clipboard

WebTransport (HTTP/3 over QUIC) for Dart and Flutter: one browser-shaped client API, backed by the browser on the web and by a bundled Rust implementation elsewhere.

example/lib/main.dart

import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:webtransport/webtransport.dart';

import 'echo_server_stub.dart' if (dart.library.io) 'echo_server_native.dart';
import 'echo_server_types.dart';

/// Demonstrates the portable client API.
///
/// On the native platforms a self-signed echo server is started in this process
/// (with the native-only library) and the client connects to it, pinning its
/// certificate exactly the way a browser does. On the web there is no local
/// server — browsers cannot listen — so the app reports that and the code below
/// is the same either way.
void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final List<String> _log = <String>[];
  LocalEchoServer? _server;
  WebTransport? _client;
  String _status = 'starting…';

  @override
  void initState() {
    super.initState();
    unawaited(_run());
  }

  @override
  void dispose() {
    unawaited(_client?.close());
    _server?.dispose();
    super.dispose();
  }

  void _note(String message) {
    if (!mounted) return;
    setState(() {
      _log.add(message);
      if (_log.length > 14) _log.removeAt(0);
    });
  }

  Future<void> _run() async {
    try {
      final server = await startLocalEchoServer();
      if (server == null) {
        _note(
          'no local echo server on this platform (the browser cannot '
          'listen for WebTransport sessions)',
        );
        if (mounted) setState(() => _status = 'idle');
        return;
      }
      _server = server;
      _note('server listening on ${server.url}');

      // The portable entry point: on the web this returns the browser
      // implementation, on the VM the native one.
      final client = createWebTransport(
        server.url,
        WebTransportOptions(serverCertificateHashes: server.certificateHashes),
      );
      _client = client;
      await client.ready.timeout(const Duration(seconds: 20));
      _note(
        'connected — reliability: ${client.reliability.name}, '
        'max datagram: ${client.datagrams.maxDatagramSize} B',
      );

      // Unreliable, unordered datagrams.
      final datagram = client.datagrams.readable.first;
      await client.datagrams.write(utf8.encode('ping via datagram'));
      _note('datagram echo: ${utf8.decode(await datagram)}');

      // A reliable, ordered bidirectional stream.
      final stream = await client.createBidirectionalStream();
      await stream.writable.write(utf8.encode('hello over a stream'));
      await stream.writable.close();
      final echo = await stream.readable.toBytes();
      _note('stream echo: ${utf8.decode(echo)}');

      await client.close(const WebTransportCloseInfo(closeCode: 0));
      _note('closed');

      if (mounted) setState(() => _status = 'ok');
    } on Object catch (error) {
      _note('failed: $error');
      if (mounted) setState(() => _status = 'failed');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('webtransport')),
        body: Padding(
          padding: const EdgeInsets.all(16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Text('status: $_status', style: const TextStyle(fontSize: 20)),
              const Divider(),
              Expanded(
                child: ListView.builder(
                  itemCount: _log.length,
                  itemBuilder: (context, index) => Text(_log[index]),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
0
likes
160
points
54
downloads

Documentation

API reference

Publisher

verified publisherunk404.com

Weekly Downloads

WebTransport (HTTP/3 over QUIC) for Dart and Flutter: one browser-shaped client API, backed by the browser on the web and by a bundled Rust implementation elsewhere.

Repository (GitHub)
View/report issues

Topics

#webtransport #quic #http3 #ffi #networking

License

MIT (license)

Dependencies

code_assets, ffi, hooks, logging, native_toolchain_rust, web

More

Packages that depend on webtransport