tokio only.Expand description
Async framing — a tokio_util::codec adapter (the tokio feature).
Async framing via tokio_util::codec — the tokio feature.
BinCodec<T> implements Decoder +
Encoder for any #[bin] message (anything that is
BitDecode/BitEncode), so wrapping a tokio stream is one line:
use bnb::BinCodec;
use tokio_util::codec::Framed;
use futures_util::{SinkExt, StreamExt};
let mut conn = Framed::new(tcp_stream, BinCodec::<MyMsg>::new());
conn.send(MyMsg::Ping).await?; // it's a `Sink<MyMsg>`
let reply = conn.next().await.unwrap()?; // …and a `Stream<Item = MyMsg>`The codec relies on each message being self-delimiting (its #[bin] structure or a
magic/length prefix bounds it) — decode reads exactly one message and returns None
when only a partial frame has arrived, so Framed reads more and retries.
Byte alignment over Framed. Framed’s buffer is byte-granular, so BinCodec
advances by whole bytes and starts each decode at a byte boundary. A message whose
encoded length is not a whole number of bytes (a sub-byte #[bin] frame) therefore
cannot be packed back-to-back on a Framed byte stream — use a byte-aligned message, or
carry the bit cursor yourself with BitBuf/MessageStream.
(Each UdpFramed datagram is framed independently, so sub-byte messages are fine there.)
The same BinCodec drives datagrams, too: tokio_util::udp::UdpFramed::new(udp_socket, BinCodec::<T>::new()) is a Stream<Item = (T, SocketAddr)> + Sink<(T, SocketAddr)>. So
one codec covers async streams (Framed, TCP) and async datagrams (UdpFramed, UDP) — the
async mirror of the sync MessageStream / MessageDatagram split. See examples/tokio_udp.
Structs§
- BinCodec
- A
tokio_util::codeccodec that frames any bnb#[bin]messageT. Construct withBinCodec::newand hand it toFramed.