AMQP 1.0
hopf-amqp1 is an AMQP 1.0 async client (ISO/IEC 19464) targeting brokers with native AMQP 1.0 support (RabbitMQ 4's native AMQP 1.0 listener, ActiveMQ Artemis). Client-only: no broker in this crate. AMQP 1.0 shares only the four-byte AMQP magic with hopf-amqp's AMQP 0-9-1 (RabbitMQ classic protocol) — framing, the type system, and the connection/session/link model are unrelated.
Scope
| Area | Support |
|---|---|
| Protocol | AMQP 1.0 (ISO/IEC 19464) only — see AMQP 0-9-1 for the separate hopf-amqp crate |
| Role | Client only |
| Auth | SASL PLAIN (when credentials are configured) or ANONYMOUS, auto-negotiated against what the peer advertises |
| Sessions / links | Multiple sessions per connection, multiple sender/receiver links per session |
| Flow control | Session-level incoming/outgoing window; per-link credit |
| Send | transfer with header/properties/application-properties/data, auto-split across frames for messages larger than the negotiated max frame size |
| Receive | Streamed to the application as transfer frames arrive, not buffered whole |
| Settlement | accept / reject / release / modify; outcome notifications for sent messages |
| TLS | AMQPS via implicit TLS on dial |
Architecture
Amqp1Client::connect
→ Runtime::connect(TcpConnectorConfig)
→ Amqp1ClientEndpoint (ProtocolHandler)
protocol header → SASL mechanisms/init/outcome (if advertised)
→ AMQP protocol header (re-armed) → open/open
→ Amqp1ClientDriver::on_connection_open
→ begin_session / attach_sender / attach_receiver via Amqp1ClientControl
← transfer (streamed) → on_message_header/properties/application_properties/data
← disposition → on_delivery_outcome
Inbound is reactor-driven: socket readable → receive → Amqp1FrameParser → MessageParser for transfer payloads → driver callbacks. There is no application poll loop. The frame parser and message-section parser are both genuinely incremental push parsers — a large message body streams to the driver as bytes arrive rather than being buffered whole first.
SASL handshake
On connect, the client sends the AMQP protocol header for the SASL sub-protocol first. If the peer advertises PLAIN and credentials are configured, PLAIN is used; otherwise the client falls back to ANONYMOUS. After a successful sasl-outcome, the connection re-arms to expect the AMQP (non-SASL) protocol header, then proceeds with open. This re-arming happens correctly even when a peer pipelines the SASL outcome and the following AMQP header into the same TCP read — a real broker commonly does this, and the frame parser handles it within a single feed() call rather than needing a second read to notice the mode switch.
Sessions and links
AMQP 1.0 layers sessions (RFC-1982 serial-numbered transfer windows over one connection) and links (named, unidirectional, credit-flow-controlled sender or receiver attachments within a session) on top of the connection — a structure AMQP 0-9-1 doesn't have. Amqp1ClientControl::begin_session opens a session on a channel; attach_sender/attach_receiver attach named links with a Source/Target address. A receiver must be given link credit (add_credit) before the peer will send it any deliveries.
Client
SPI mirrors the other Hopf async clients: Amqp1Client facade, Amqp1ClientHandlerFactory, flat Amqp1ClientDriver / Amqp1ClientControl.
Amqp1Client::new("127.0.0.1", 5672)
.credentials("guest", "guest")
.connect(&rt, Arc::new(Factory))?;
On on_connection_open, begin a session; on on_session_begin, attach a sender and/or receiver; on on_link_attached for a receiver, call add_credit before expecting deliveries; on on_credit for a sender, send is safe to call.
Messages
MessageHeader (durability, priority, TTL, …) and MessageProperties (content-type, message-id, correlation-id, …) are list-based sections; application-properties, delivery-annotations, and message-annotations are bare maps, encoded/decoded as such (not wrapped in a list — a spec-correctness detail this crate gets right). delivery-annotations, message-annotations, and footer sections are received as raw maps but not yet offered on the send side.
Examples
cargo test -p hopf-amqp1 --lib client::tests
cargo test -p hopf-amqp1 --features integration
No standalone cargo run example binary ships yet (unlike hopf-amqp's amqp-pub/amqp-consume) — see the client module docs for a full quick-start (connect, begin a session, attach a sender, send a message). The opt-in integration test targets a broker with native AMQP 1.0 support; defaults to 127.0.0.1:5672 / guest/guest (RabbitMQ 4 node addressing, /queues/<name>), overridable with HOPF_AMQP1_HOST, HOPF_AMQP1_PORT, HOPF_AMQP1_USER, HOPF_AMQP1_PASS, and HOPF_AMQP1_ADDRESS_STYLE=artemis for a plain queue-name address instead. HOPF_AMQP1_TLS_PORT / HOPF_AMQP1_TLS_CA configure the amqps (implicit TLS) test; it's skipped if no CA cert is found.
Limitations
- No automatic reconnection (unlike
hopf-amqp'sAmqpRecoveringClient) - No heartbeat send, and no enforcement of a peer's advertised
idle-time-out; advertises no requirement of its own. Fine for short-lived or steadily-busy connections; a long-idle connection against a broker with a strict idle timeout could be dropped delivery-annotations,message-annotations, andfootermessage sections are received (raw maps) but not yet offered on the send side- No broker / server module, and no transactions
- No Composition/XML registration in v1