Async Sockets
ZZ I/O is non-blocking by default. This guide covers the two network surfaces: HTTP for web traffic and TCP sockets for everything else.
Async HTTP client
Section titled “Async HTTP client”Client calls return Result<Response, str> — handle both arms:
import std.http
match http.get("https://api.example.com/users/1", {}) { .ok(res) => { println(http.status(res)) println(http.text(res)) }, .err(e) => println("request failed: {e}"),}Post JSON with explicit headers:
import std.httpimport std.json
payload := json.stringify({"name": "Ada"})headers := {"content-type": "application/json"}
match http.post("https://api.example.com/users", payload, headers) { .ok(res) => println("created: {http.status(res)}"), .err(e) => println("request failed: {e}"),}Async HTTP server
Section titled “Async HTTP server”Build a route table with pipelines, then listen. Handlers take the request and return the response body:
import std.http
server := http.server() |> http.get(_, "/", |body: str| "Hello, World!") |> http.post(_, "/echo", |body: str| body)
http.listen(server, 8080)Prove routes with http.handle before ever opening a port:
response := http.handle(server, "GET", "/", "")println(response) // Hello, World!Raw TCP
Section titled “Raw TCP”Drop to std.net when the protocol isn’t HTTP. Every call
returns a Result:
import std.net
match net.tcp_connect("example.com:80", 5000) { .ok(stream) => { net.tcp_write(stream, "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n") match net.tcp_readline(stream) { .ok(line) => println("status: {line}"), .err(e) => println("read failed: {e}"), } net.tcp_close(stream) }, .err(e) => println("connect failed: {e}"),}Serve with tcp_listen + tcp_accept in a loop, and set deadlines with
set_read_timeout / set_write_timeout so slow peers can’t hang you.