Clients
Crate hopf-core dial path (TcpConnectorConfig / Runtime::connect) is the peer of listen. Protocol crates supply client ProtocolHandlers or HTTP ClientHandlers. DNS name dials use hopf-dns::RuntimeDnsExt.
Contents
Dial path
Runtime::connect(TcpConnectorConfig)
│
▼
pick worker (dial round-robin) ──affinity──► Reactor
│
▼
TCP connect → optional TLS-from-dial
│
▼
ProtocolHandler::connected / receive / …
Listen and dial share TcpConnParams (buffer caps, idle, TLS). Affinity is chosen at dial time and held for the connection’s life — same as accept.
use hopf_core::{ProtocolHandler, Runtime, TcpConnectorConfig};
rt.connect(TcpConnectorConfig::new(addr, move || {
Box::new(MyClient) as Box<dyn ProtocolHandler>
}))?;Optional TLS-from-dial uses the same in-tree hopf-core::tls stack as listeners: a SharedTlsConnector from connector_from_pem, public_trust_connector, or another PEM builder, then TcpConnectorConfig::with_tls(connector, server_name). TcpConnection drives TlsVariant until ProtocolHandler::security_established. Details: TLS → Wiring.
TcpConnectorConfig
| Field | Default | Notes |
|---|---|---|
addr |
required | Pre-resolved SocketAddr (Stage 0) |
factory |
required | Per-dial ProtocolHandler |
max_net_in / max_net_out |
1 MiB / 4 MiB | Same caps as listen |
idle_timeout |
None |
Partially wired — see runtime-options.md |
secure + tls |
off | TLS-from-dial |
server_name |
optional | SNI / cert verification |
connect_timeout |
None |
TCP connect budget (Some(Duration)) |
Full table: runtime-options.md.
connect_by_name
use std::sync::Arc;
use hopf_dns::RuntimeDnsExt;
// RuntimeDnsExt is implemented for Arc<Runtime>.
// Returns immediately; DNS + dial run asynchronously.
rt.connect_by_name("example.com", 443, move || {
Box::new(MyClient) as Box<dyn hopf_core::ProtocolHandler>
})?;| Behaviour | Detail |
|---|---|
| Literal IP | Skips DNS; dials immediately |
| Hostname | Async DnsResolver::resolve → first address → Runtime::connect from the callback |
| Receiver | Arc<Runtime> (so the DNS callback can dial without parking the caller) |
See dns.md.
Client handlers by protocol
| Protocol | Client surface |
|---|---|
| Raw TCP | ProtocolHandler on TcpConnectorConfig |
| HTTP/1.1 | connect_http / H1Endpoint::client + ClientHandlerFactory |
| HTTP/2 | connect_http (http2) / H2Endpoint::client + ClientHandlerFactory |
| HTTP/3 | connect_h3 + ClientHandlerFactory |
| FTP | FtpClient + FtpPipeline (FtpGet / FtpPut) in hopf-ftp |
| SMTP | SmtpClient + SmtpSend (or custom SmtpClientHandlerFactory) in hopf-smtp |
| POP3 | Pop3Client + Pop3Fetch (or custom Pop3ClientHandlerFactory) in hopf-pop3 |
| IMAP | ImapClient + ImapFetch / ImapIdle (or custom ImapClientHandlerFactory) in hopf-imap |
| LDAP | LdapClient / LdapSession (bind, search, unbind) in hopf-ldap; LdapCredentialStore for AUTH |
| MQTT | MqttClient + MqttClientDriver / MqttClientControl in hopf-mqtt |
| AMQP 0-9-1 | AmqpClient + AmqpClientDriver / AmqpClientControl in hopf-amqp (client-only) |
| gRPC | GrpcClient::unary_call → ClientHandlerFactory |
| QUIC (non-H3) | connect_quic / RuntimeQuicExt::connect_quic |
HTTP client
use std::sync::Arc;
use hopf_http::{ClientHandlerFactory, HttpLimits};
use hopf_http::client::{connect_http, HttpClientTimeouts};
connect_http(
&rt, // &Arc<Runtime>
"example.com", // hostname or literal
80,
Arc::clone(&factory),
HttpLimits::default(),
false, // http2 prior-knowledge
HttpClientTimeouts::default(),
None, // optional DnsResolver
)?;ClientHandler::start writes the request; response callbacks follow. Demo: examples/http-get. Deep dive: http/client.md.
http-get flags (summary)
| Flag | Effect |
|---|---|
--http2 / --h2 |
H2 prior-knowledge |
--http3 / --h3 |
connect_h3 (needs --ca) |
--ca <pem> |
H3 trust PEM |
--server-name <name> |
H3 SNI (default localhost) |
QUIC dial
use hopf_quic::{connect_quic, QuicConnectConfig};
// or RuntimeQuicExt::connect_quic
// H3: hopf_http::connect_h3(...)See quic-h3.md.
Examples
| Example | Dial style |
|---|---|
examples/http-get |
H1 / H2 / H3 Stream client |
examples/ftp-get |
Async FtpClient + FtpGet |
examples/smtp-send |
Async SmtpClient + SmtpSend |
examples/tls-echo |
TLS dial twin of tls-echo server |
Limitations
- Stage-0 TCP dials need a resolved
SocketAddrunless usingconnect_by_nameor protocol helpers that resolve (connect_http,SmtpClient,FtpClient). connect_by_namerequiresArc<Runtime>; it schedules DNS asynchronously and returns immediately.- QUIC dials likewise require a resolved UDP address today (H3-by-name still uses a blocking system resolve in the helper).
See also
- Services
- HTTP client
- DNS
- QUIC / H3
- Composition —
<dial-tcp>