If you're implementing your own protocol on iroh connections, you might run into the issue that the atomic unit of data you can send on a stream is a single byte. So if you want to send multiple "messages" on the same stream, you need to tell the other side where these messages begin and end. This is process is called "framing" in networking terms.
In this example we're sending chess moves back and forth on the same bi-directional stream.
To do this, we use the codec feature from the tokio-util crate.
It works like this:
- The
SendStreamandRecvStreamthat we get fromiroh::Connection::open_biimplement theAsyncWriteandAsyncWritetraits, respectively. These allow us to send and receive byte streams without framing. - We wrap these streams using
tokio_util::codec::FramedReadandFramedWriteusing aLengthDelimitedCodec. These wrappers take a codec and anAsyncRead/AsyncWriteand turn them into afutures_util::Stream/futures_util::Sink, respectively. StreamandSinkwork on messages, not byte streams, so now we can send framed "chunks" ofbytes::Byteson our streams. This works by using theLengthDelimitedCodecfor framing, it essentially prefixes our messages with a big-endian encoded u32 representing the length of the message that follows it. This way the receiving end always knows where a message begins and ends.- Finally we use
postcardandserdeto serialize and deserialize ourMovestruct into and from bytes.