nng-rs / Rust pattern guide

pair communication topology

PAIR — Two Way Radio

PAIR connects exactly two peers, each of which can send and receive freely.

nng-rs is an independently maintained Rust binding for NNG. Its maintainers and release cycle are separate from the NNG core project.

This guide is based on the project’s default-branch example, with each peer sending before its first receive so the pair can start exchanging messages. See the upstream example for its current history.

pair.rs

//! Pair (two way radio) example.
//!
//! The pair pattern is used when there is a one-to-one peer relationship. Only one peer may be
//! connected to another peer at a time but both may speak freely.
//!
//! This example was derived from [this NNG example][1].
//!
//! [1]: https://nanomsg.org/gettingstarted/nng/pair.html
use nng::{Error, Message, Protocol, Socket};
use std::{env, io::Write, process, str, thread, time::Duration};

/// Entry point of the application.
pub fn main() -> Result<(), Error> {
    let args: Vec<_> = env::args().take(3).collect();

    match &args[..] {
        [_, t, url] if t == "node0" => node0(url),
        [_, t, url] if t == "node1" => node1(url),
        _ => {
            println!("Usage: pipeline node0|node1 <URL> <ARG> ...");
            process::exit(1);
        }
    }
}

/// The listening node.
fn node0(url: &str) -> Result<(), Error> {
    let s = Socket::new(Protocol::Pair0)?;
    s.listen(url)?;

    send_recv(&s, "NODE0")
}

/// The dialing node.
fn node1(url: &str) -> Result<(), Error> {
    let s = Socket::new(Protocol::Pair0)?;
    s.dial(url)?;

    send_recv(&s, "NODE1")
}

/// Sends and receives messages on the socket.
fn send_recv(s: &Socket, name: &str) -> Result<(), Error> {
    loop {
        thread::sleep(Duration::from_secs(1));
        let mut msg = Message::new();
        write!(msg, "{}", name).expect("failed to write to message");
        println!("{0}: SENDING \"{0}\"", name);
        s.send(msg)?;

        let msg = s.recv()?;
        let partner = str::from_utf8(&msg).expect("invalid UTF-8 message");
        println!("{}: RECEIVED \"{}\"", name, partner);
    }
}
      
Run it

# Set up once.
git clone --recurse-submodules https://github.com/nanomsg/nng-rs.git
cd nng-rs

# Run these in separate terminals from the checkout.
cargo run -p nng --example pair -- node0 tcp://127.0.0.1:6002
cargo run -p nng --example pair -- node1 tcp://127.0.0.1:6002