Communicate over QUIC
Warning: This is an unstable API that is subject to change or removal at any time.
QUIC is the transport protocol underneath HTTP/3. It runs over UDP, always encrypts with TLS, connects faster than TCP plus TLS, and one connection carries many independent streams with no head-of-line blocking. This example starts a QUIC server and client in one process and echoes a message over a bidirectional stream. QUIC always requires TLS, so the server needs a certificate. For local development, generate a self-signed one (note CA:FALSE, clients reject certificates marked as CA when used by a server): openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost" -addext "basicConstraints=critical,CA:FALSE"
const cert = Ende.readTextFileSync("./server.crt");
const key = Ende.readTextFileSync("./server.key");A QuicEndpoint binds a UDP socket. Listening on it takes the TLS configuration; ALPN protocol names are required and both sides must agree on one.
const endpoint = new Ende.QuicEndpoint({ hostname: "localhost", port: 4433 });
const listener = endpoint.listen({ cert, key, alpnProtocols: ["echo"] });The server accepts connections, and on each connection accepts incoming bidirectional streams. Each stream is an independent, ordered, reliable channel: a pair of web streams, just like other Ende networking APIs.
(async () => {
for await (const incoming of listener) {
const conn = await incoming.accept();
const { value: stream } = await conn.incomingBidirectionalStreams
.getReader().read();
if (!stream)
continue;
const message = await new Response(stream.readable).text();
const writer = stream.writable.getWriter();
await writer.write(new TextEncoder().encode(`echo: ${message}`));
await writer.close();
}
})();Connect as a client. caCerts trusts our self-signed certificate; with a real certificate it is not needed.
const client = await Ende.connectQuic({
alpnProtocols: ["echo"],
caCerts: [cert],
hostname: "localhost",
port: 4433
});Open a bidirectional stream, send a message, close our sending side, and read the reply.
const stream = await client.createBidirectionalStream();
const writer = stream.writable.getWriter();
await writer.write(new TextEncoder().encode("hello over QUIC"));
await writer.close();
console.log(await new Response(stream.readable).text()); // echo: hello over QUIC
client.close();
endpoint.close();Run this example locally using the Ende CLI:
ende run --unstable-net --allow-net --allow-read https://docs.ende.sh/examples/scripts/quic.ts