13 releases

0.6.0 Mar 3, 2023
0.5.1 May 23, 2022
0.5.0-alpha9 Apr 26, 2022
0.5.0-alpha8 Jan 25, 2022
0.5.0-alpha1 Aug 31, 2021

#1216 in Procedural macros

Download history 9/week @ 2022-11-25 7/week @ 2022-12-02 13/week @ 2022-12-09 7/week @ 2022-12-16 17/week @ 2022-12-23 3/week @ 2022-12-30 8/week @ 2023-01-06 4/week @ 2023-01-13 8/week @ 2023-01-20 10/week @ 2023-01-27 10/week @ 2023-02-03 25/week @ 2023-02-10 22/week @ 2023-02-17 12/week @ 2023-02-24 23/week @ 2023-03-03 30/week @ 2023-03-10

99 downloads per month
Used in fizyr-rpc

BSD-2-Clause OR Apache-2.0

1.5K SLoC

Docs.rs Tests


Rust implementation of the Fizyr RPC procotol.

The Fizyr RPC protocol is a request/response protocol, with bi-directional feedback as long as a request is open. Additionally, you can send individual stream messages that do not initiate a request.


Peer and PeerHandle

As a user of the library, you will mostly be using the PeerHandle object. The PeerHandle is used to interact with a remote peer. It is used to send and receive requests and stream messages. It can also be split in a PeerReadHandle and a PeerWriteHandle, to allow moving the handles into different tasks. The write handle can also be cloned and used in multiple tasks.

To obtain a PeerHandle, you can call Peer::connect(). This will connect to a remote listener and spawn a background task to read and write messages over the connection. If you need full control over tasks, you can instead create a Peer object and call Peer::run() manually.


The [Listener] struct is used to accept incoming connections and gives you a PeerHandle for each incoming connection. You can then use the handle to process incoming messages and to send messages to the peer. Usually, you will want to spawn a task for each accepted connection that handles the communication.


Each peer internally uses a Transport. The transport is responsible for reading and writing raw messages. By abstracting away the message transport, the library can expose a single generic Peer and [Listener] struct.

There are different transports for different socket types. Different transports may also use different types as message body. For example, the TcpTransport and UnixStreamTransport use messages with a StreamBody. This StreamBody body type contains raw bytes.

The UnixSeqpacketTransport has messages with a UnixBody, which allows you to embed file descriptors with each message.


The library uses features to avoid unnecessarily large dependency trees. Each feature corresponds to a different transport type. None of the features are enabled by default. Currently, the library has these features:


use fizyr_rpc::{TcpPeer, StreamConfig};

let (peer, info) = TcpPeer::connect("localhost:1337", StreamConfig::default()).await?;
eprintln!("Connected to: {}", info.remote_address());
let mut request = peer.send_request(1, &b"Hello World!"[..]).await?;

while let Some(update) = request.recv_update().await {
    let body = std::str::from_utf8(&update.body)?;
    eprintln!("Received update: {}", body);

let response = request.recv_response().await?;
let body = std::str::from_utf8(&response.body)?;
eprintln!("Received response: {}", body);


~26K SLoC