Nanomsg library for Rust

Overview

Nanomsg

Cargo 0.7.2 MIT License Build Status Build status

Documentation

Nanomsg is a modern messaging library that is the successor to ZeroMQ, written in C by Martin Sustrik and colleagues. The nanomsg library is licensed under MIT/X11 license. "nanomsg" is a trademark of 250bpm s.r.o.

Requirements

  • Nanomsg 1.1.4

Installing nanomsg:

make deps

Installation

[dependencies]
nanomsg = "0.7.2"

Simply import the crate to use it:

use nanomsg;

Creating a Socket

The basis of Nanomsg is a Socket. Each socket can be of a certain type. The type of a socket defines it's behaviour and limitations (such as only being able to send and not receive).

use nanomsg::{Socket, Protocol, Error};

/// Creating a new `Pull` socket type. Pull sockets can only receive messages
/// from a `Push` socket type.
fn create_socket() -> Result<(), Error> {
    let mut socket = Socket::new(Protocol::Pull)?;
    Ok(())
}

Now, each socket that is created can be bound to multiple endpoints. Each binding can return an error, so we'll take advantage of the ? (try) operator.

use nanomsg::{Socket, Protocol, Error};

/// Creating a new `Pull` socket type. Pull sockets can only receive messages
/// from a `Push` socket type.
fn create_socket() -> Result<(), Error> {
    let mut socket = Socket::new(Protocol::Pull)?;
    
    // Create a new endpoint bound to the following protocol string. This returns
    // a new `Endpoint` that lives at-most the lifetime of the original socket.
    let mut endpoint = socket.bind("ipc:///tmp/pipeline.ipc")?;

    Ok(())
}

The socket is ready to be used now!

Because this is a Pull socket, we'll implement reading any messages we receive.

// ... After the endpoint we created, we'll start reading some data.
let mut msg = String::new();
loop {
    socket.read_to_string(&mut msg)?;
    println!("We got a message: {}", &*msg);
    msg.clear();
}
// ...

That's awesome! But... we have no packets being sent to the socket, so we'll read nothing. To fix this, let's implement the accompanying pair Push socket.

use nanomsg::{Socket, Protocol, Error};

fn pusher() -> Result<(), Error> {
    let mut socket = Socket::new(Protocol::Push)?;
    let mut endpoint = socket.connect("ipc:///tmp/pipeline.ipc")?;

    socket.write(b"message in a bottle");

    endpoint.shutdown();
    Ok(())
}

Contributors

(In arbitrary order):

License

The MIT License (MIT)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Comments
  • API doesn't work with Reader API

    API doesn't work with Reader API

    I 've made some test with the new API and I can't manage to use it with the Reader API method like read_to_end or read_to_string. I dig a little and I found that the read method should send EndOfFile error when the buffer has been read. The nanomsg.rs Read method read all the buffer and send it back or wait for incomming data. So whren using read_to_string for example, the call is blocked all the time because the nanomasg Read is call twice and block in the second call. I think other mthod of the Reader API should be overrided. read_to_end for example. Have you planned to make them?

    api 
    opened by musitdev 19
  • can not build at debian

    can not build at debian

    error[E0252]: a value named ENOTSUP has already been imported in this module --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/nanomsg-sys-0.6.0/src/lib.rs:7:9 | 5 | pub use libc::; | -------- previous import of ENOTSUP here 6 | 7 | pub use posix_consts::; | ^^^^^^^^^^^^^^^^ already imported

    error[E0255]: a value named ENOTSUP has already been imported in this module --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/nanomsg-sys-0.6.0/src/lib.rs:85:5 | 72 | use libc::*; | -------- previous import of ENOTSUP here ... 85 | pub const ENOTSUP: c_int = NN_HAUSNUMERO + 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ENOTSUP was already imported

    error: aborting due to 2 previous errors

    opened by ksaritek 12
  • Implement nn_poll()

    Implement nn_poll()

    This implements the rust-safe version of nn_poll(). Because of the way nn_poll operates, it is possible that an error flag is set, so this commit also implements nn_errno().

    There is already a NanoErr, which appears to be a very light wrapper around the error number and an error string. This didn't feel very "rusty" to me, so I added an error enum which matches the NanoMsg errors. This allows pattern matching on the the errors and makes for much cleaner syntax (I think). Open to opinions/changes.

    The enum is currently called NanoError, which is confusingly similar to NanoErr...it should probably be renamed

    poll() accepts three parameters:

    • send (bool): check if this socket can send a message
    • receive (bool): check if this socket can receive a message (e.g. a pending message is waiting)
    • timeout (int): how long to wait before returning with an error

    poll() returns a Result, containing either:

    • (send, receive) = Ok((bool, bool))
    • error = Err(NanoError)

    The second commit in this PR implements two convenience methods (can_send and can_receive), which make it easier to interact with the poll method if you just want a true/false response (instead of dealing with error handling).

    Edit: typos fixed

    opened by polyfractal 12
  • 32 bit build error

    32 bit build error

    I experienced build errors on a 32 bit Linux machine:

    cargo build
       Compiling link-config v0.1.1 (https://github.com/alexcrichton/link-config.git#9a30a0bf)
       Compiling nanomsg-sys v0.1.0 (https://github.com/thehydroimpulse/nanomsg.rs.git#771d7913)
       Compiling nanomsg v0.3.0 (https://github.com/thehydroimpulse/nanomsg.rs.git#771d7913)
    /home/vagrant/.cargo/git/checkouts/nanomsg.rs-87a2823cf330bb35/master/src/lib.rs:405:17: 405:35 error: mismatched types:
     expected `u32`,
        found `u64`
    (expected u32,
        found u64) [E0308]
    /home/vagrant/.cargo/git/checkouts/nanomsg.rs-87a2823cf330bb35/master/src/lib.rs:405                 libnanomsg::NN_MSG,
                                                                                                         ^~~~~~~~~~~~~~~~~~
    /home/vagrant/.cargo/git/checkouts/nanomsg.rs-87a2823cf330bb35/master/src/lib.rs:874:17: 874:35 error: mismatched types:
     expected `u32`,
        found `u64`
    (expected u32,
        found u64) [E0308]
    /home/vagrant/.cargo/git/checkouts/nanomsg.rs-87a2823cf330bb35/master/src/lib.rs:874                 libnanomsg::NN_MSG,
                                                                                                         ^~~~~~~~~~~~~~~~~~
    error: aborting due to 2 previous errors
    Could not compile `nanomsg`.
    

    Looks like libnanomsg::NN_MSG is defined as a very large u64:

    pub const NN_MSG: u64 = -1;
    

    however nn_recv expects a libc::size_t which is apparently a u32 on this platform:

    pub fn nn_recv(socket: c_int, buf: *mut c_void, len: size_t, flags: c_int) -> c_int;
    

    Not sure what the proper fix is yet.

    $ cargo --version
    cargo 0.0.1-pre-nightly (dfd4868 2015-02-06 22:55:29 +0000)
    $ rustc --version
    rustc 1.0.0-dev (725cc0646 2015-02-08 12:35:03 +0000)
    
    Ubuntu 14.04.1 LTS
    
    opened by nyx 11
  • Improve drop implementation

    Improve drop implementation

    The drop function implementation is currently passing a value of 0 for the parameter how of the nn_shutdown function. The nanomsg documentation states that the return value of the prior call to bind and/or connect should be used instead. It looks like nn_close should also be called.

    discussion 
    opened by blabaere 11
  • Fix static build of bundled nanomsg

    Fix static build of bundled nanomsg

    When building with musl as a target, build fails like so:

    % cargo build --target=x86_64-unknown-linux-musl --release
    
    ...
    
    CMake Error at cmake_install.cmake:94 (file):
      file RPATH_CHANGE could not write new RPATH:
    
        /home/user/rust/project/target/x86_64-unknown-linux-musl/release/build/nanomsg-sys-80e249f9b2c26403/out/lib64
    
      to the file:
    
        /home/user/rust/project/target/x86_64-unknown-linux-musl/release/build/nanomsg-sys-80e249f9b2c26403/out/bin/nanocat
    
      No valid ELF RPATH or RUNPATH entry exists in the file;
    
    ...
    
    

    A hint can be found in https://github.com/FreeRDP/FreeRDP/issues/2150. This patch seems to fix this issue here, and I can build a working static binary.

    opened by rsdy 8
  • Tests hang and don't seem to finish

    Tests hang and don't seem to finish

    When running the tests, only 41 out of 42 finish.

    ► rustc --version
    rustc 1.9.0-nightly (998a6720b 2016-03-07)
    ► pacman -Q nanomsg
    nanomsg 0.8-1
    ► cargo test
         Running target/debug/nanomsg-da8752b8a62b8468
    
    running 42 tests
    test result::tests::can_convert_error_code_to_error ... ok
    test result::tests::nano_err_can_be_converted_to_io_err ... ok
    test tests::bool_to_c_int_sanity ... ok
    test result::tests::nano_err_can_be_converted_from_io_err ... ok
    test tests::check_allocate ... ok
    test tests::initialize_socket ... ok
    test tests::connect_and_shutdown ... ok
    test tests::bind_and_shutdown ... ok
    test tests::bind_socket ... ok
    test tests::bus ... ok
    test tests::nb_write_works_in_both_cases ... ok
    test tests::pipeline_mt1 ... ok
    test tests::pipeline ... ok
    test tests::pair ... ok
    test tests::protocol_matches_raw ... ok
    test tests::pipeline_mt2 ... ok
    test tests::should_change_ipv4_only ... ok
    test tests::should_change_linger ... ok
    test tests::should_change_max_reconnect_interval ... ok
    test tests::should_change_receive_buffer_size ... ok
    test tests::should_change_receive_priority ... ok
    test tests::should_change_receive_timeout ... ok
    test tests::should_change_reconnect_interval ... ok
    test tests::should_change_request_resend_interval ... ok
    test tests::should_change_send_buffer_size ... ok
    test tests::should_change_send_priority ... ok
    test tests::should_change_send_timeout ... ok
    test tests::should_change_socket_name ... ok
    test tests::should_change_tcp_nodelay ... ok
    test tests::should_get_receive_fd ... ok
    test tests::should_get_send_fd ... ok
    test tests::should_get_socket_name ... ok
    test tests::nb_read_works_in_both_cases ... ok
    test tests::nb_read_to_end_works_in_both_cases ... ok
    test tests::connect_push_to_multi_ep ... ok
    test tests::read_when_buffer_is_smaller_than_msg_return_buffer_size ... ok
    test tests::bind_pull_to_multi_ep ... ok
    test tests::poll_works ... ok
    test tests::zero_copy_works ... ok
    test tests::test_read_to_end ... ok
    test tests::pubsub ... ok
    ^C
    
    opened by vks 8
  • Change 2 booleans to 1 enum

    Change 2 booleans to 1 enum

    Since socket.new_pollfd(false, false) is not a particularly useful state to be in, change this API to use an enum instead of 2 booleans. This allows us to limit the API to only the states that are actually useful

    opened by pwoolcoc 8
  • Add feature 'bundled' as a way to provide nanomsg as part of the cargo build.

    Add feature 'bundled' as a way to provide nanomsg as part of the cargo build.

    I bumped the package versions up to 0.7 as well.

    This shouldn't break or change the default behavior that was previously used but if it does then I'm happy to figure out why and update the PR.

    opened by photex 6
  • Adds socket option setters

    Adds socket option setters

    Adds the required constant in libnanomsg. Adds the socket option setters in main lib. Changes the parameter type of set_survey_deadline to &Duration.

    opened by blabaere 6
  • Upgrade to nanomsg 0.9

    Upgrade to nanomsg 0.9

    Obviously:

    • Upgrade nanomsg native dependency to version 1.0.0

    But also:

    • libnanomsg is now used as dynamic library
    • libnanomsg is now built using cmake (as recommended since 0.9)

    The Windows build on Appveyor changed too:

    • Using Visual Studio instead of mingw
    • Moved to x64
    opened by blabaere 5
  • Ability to pass directory of C library

    Ability to pass directory of C library

    I would like to be able to somehow pass path to the C sources of nanomsg, when feature bundled is set - that way I don't have to rely on git and I can easily choose which version of nanomsg will the crate be compiled against. Is it doable and if so would maintainers consider incorporating this feature into the crate?

    I can see that nanomsg-sys checks if nanomsg/.git path exists, but it's not clear to me that working directory is it checking - I have C nanomsg in my project directory as git's submodule but it doesn't look like nanomsg-sys finds it.

    opened by fuine 6
  • Examples from the doc not working.

    Examples from the doc not working.

    rustc 1.11.0 (9b21dcd6a 2016-08-15)

    src/main.rs:4:5: 4:26 error: unresolved import `std::io::timer::sleep`. Could not find `timer` in `std::io` [E0432]
    src/main.rs:4 use std::io::timer::sleep;
                      ^~~~~~~~~~~~~~~~~~~~~
    src/main.rs:4:5: 4:26 help: run `rustc --explain E0432` to see a detailed explanation
    src/main.rs:3:5: 3:34 error: module `duration` is private
    src/main.rs:3 use std::time::duration::Duration;
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/main.rs:12:28: 12:34 error: mismatched types [E0308]
    src/main.rs:12     let mut buffer = [0u8, ..1024];
                                              ^~~~~~
    src/main.rs:12:28: 12:34 help: run `rustc --explain E0308` to see a detailed explanation
    src/main.rs:12:28: 12:34 note: expected type `u8`
    src/main.rs:12:28: 12:34 note:    found type `std::ops::RangeTo<_>`
    src/main.rs:14:11: 14:33 error: no associated item named `milliseconds` found for type `std::time::Duration` in the current scope
    src/main.rs:14     sleep(Duration::milliseconds(50));
                             ^~~~~~~~~~~~~~~~~~~~~~
    src/main.rs:16:23: 16:28 error: no method named `write` found for type `nanomsg::Socket` in the current scope
    src/main.rs:16     match push_socket.write(b"foobar") {
                                         ^~~~~
    src/main.rs:16:23: 16:28 help: items from traits can only be used if the trait is in scope; the following trait is implemented but not in scope, perhaps add a `use` for it:
    src/main.rs:16:23: 16:28 help: candidate #1: `use std::io::Write`
    src/main.rs:21:23: 21:27 error: no method named `read` found for type `nanomsg::Socket` in the current scope
    src/main.rs:21     match pull_socket.read(&mut buffer) {
                                         ^~~~
    src/main.rs:21:23: 21:27 help: items from traits can only be used if the trait is in scope; the following trait is implemented but not in scope, perhaps add a `use` for it:
    src/main.rs:21:23: 21:27 help: candidate #1: `use std::io::Read`
    error: aborting due to 4 previous errors
    error: Could not compile `nanomsgtest`.
    
    opened by lunemec 1
  • Compiled documentation is out of date.

    Compiled documentation is out of date.

    The linked documentation at http://thehydroimpulse.github.io/nanomsg.rs/nanomsg/struct.Socket.html does not match the actual code in the repository (the type signature of read_to_end is what tripped me up).

    opened by Parakleta 6
  • Relicense under dual MIT/Apache-2.0

    Relicense under dual MIT/Apache-2.0

    Why?

    The MIT license requires reproducing countless copies of the same copyright header with different names in the copyright field, for every MIT library in use. The Apache license does not have this drawback, and has protections from patent trolls and an explicit contribution licensing clause. However, the Apache license is incompatible with GPLv2. This is why Rust is dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for GPLv2 compat), and doing so would be wise for this project. This also makes this crate suitable for inclusion in the Rust standard distribution and other project using dual MIT/Apache.

    How?

    To do this, get explicit approval from each contributor of copyrightable work (as not all contributions qualify for copyright) and then add the following to your README:

    ## License
    
    Licensed under either of
     * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
     * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
    at your option.
    
    ### Contribution
    
    Unless you explicitly state otherwise, any contribution intentionally submitted
    for inclusion in the work by you shall be dual licensed as above, without any
    additional terms or conditions.
    

    and in your license headers, use the following boilerplate (based on that used in Rust):

    // Copyright (c) 2015 t developers
    // Licensed under the Apache License, Version 2.0
    // <LICENSE-APACHE or
    // http://www.apache.org/licenses/LICENSE-2.0> or the MIT
    // license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
    // at your option. All files in the project carrying such
    // notice may not be copied, modified, or distributed except
    // according to those terms.
    

    And don't forget to update the license metadata in your Cargo.toml!

    Contributor checkoff

    • [x] @blabaere
    • [x] @thehydroimpulse
    • [ ] @glycerine
    • [x] @dcbishop
    • [x] @Ryman
    • [x] @lawlerd
    • [x] @GGist
    • [x] @polyfractal
    • [x] @danburkert
    • [x] @bfops
    • [x] @musitdev
    • [x] @mystal
    • [x] @pwoolcoc
    opened by emberian 14
  • cant build from osx 10.11

    cant build from osx 10.11

    Downloading nanomsg v0.4.2 thread '' panicked at 'called Result::unwrap() on an Err value: A requested feature, protocol or option was not found built-in in this libcurl due to a build-time decision.', ../src/libcore/result.rs:732 thread '

    ' panicked at 'called Result::unwrap() on an Err value: Any', ../src/libcore/result.rs:732

    opened by imiskolee 1
  • Master tracking 1.0 or nightly ?

    Master tracking 1.0 or nightly ?

    @thehydroimpulse I noticed the appveyor script is using the nightly build of rust while the travis one is using version 1.0.0. How do we go on with this now ?

    @GGist This means that as long as the travis build is ok, the appveyor should be ok too, but the opposite maybe true only as long as no new feature of rust are used.

    opened by blabaere 1
Owner
Daniel Fagnan
Canadian working @twitchtv
Daniel Fagnan
A µTP (Micro/uTorrent Transport Library) library implemented in Rust

rust-utp A Micro Transport Protocol library implemented in Rust. API documentation Overview The Micro Transport Protocol is a reliable transport proto

Ricardo Martins 134 Dec 11, 2022
A library to work with CIDRs in rust

ipnetwork This is a library to work with IPv4 and IPv6 CIDRs in Rust Run Clippy by doing rustup component add clippy cargo clippy Installation This c

Abhishek Chanda 98 Dec 12, 2022
A Constrained Application Protocol(CoAP) library implemented in Rust.

coap-rs A fast and stable Constrained Application Protocol(CoAP) library implemented in Rust. Features: CoAP core protocol RFC 7252 CoAP Observe optio

Covertness 170 Dec 19, 2022
Backroll is a pure Rust implementation of GGPO rollback networking library.

backroll-rs Backroll is a pure Rust implementation of GGPO rollback networking library. Development Status This is still in an untested alpha stage. A

Hourai Teahouse 273 Dec 28, 2022
A Rust library for parsing the SOME/IP network protocol (without payload interpretation).

someip_parse A Rust library for parsing the SOME/IP network protocol (without payload interpretation). Usage Add the following to your Cargo.toml: [de

Julian Schmid 18 Oct 31, 2022
A library for easily creating WebRTC data channel connections in Rust

Cyberdeck A library for easily creating WebRTC data channel connections in Rust.

RICHΛRD ΛNΛYΛ 34 Nov 10, 2022
Modrinth API is a simple library for using Modrinth's API in Rust projects

Ferinth is a simple library for using the Modrinth API in Rust projects. It uses reqwest as its HTTP(S) client and deserialises responses to typed structs using serde.

null 20 Dec 8, 2022
An LV2 host library for Rust.

Livi A library for hosting LV2 plugins. Note: This is a work in progress and has not yet been full tested. Supported LV2 Features LV2 has a simple cor

Will 11 Nov 8, 2022
A Rust compiler plugin and support library to annotate overflow behavior

overflower This project contains a compiler plugin and supporting library to allow the programmer to annotate their code to declare how integer overfl

null 104 Nov 28, 2022
Dav-server-rs - Rust WebDAV server library. A fork of the webdav-handler crate.

dav-server-rs A fork of the webdav-handler-rs project. Generic async HTTP/Webdav handler Webdav (RFC4918) is defined as HTTP (GET/HEAD/PUT/DELETE) plu

messense 30 Dec 29, 2022
Peer-to-peer communications library for Rust based on QUIC protocol

qp2p Crate Documentation MaidSafe website SAFE Dev Forum SAFE Network Forum Overview This library provides an API to simplify common tasks when creati

MaidSafe 337 Dec 14, 2022
A BitTorrent V1 engine library for Rust (and currently Linux)

cratetorrent Cratetorrent is a Rust crate implementing the BitTorrent version 1 protocol. It can be used as a library and also provides a simple examp

null 401 Dec 28, 2022
Rust library that helps you change the domain of the link to another domain 🦀🔐

Rust library that helps you to change the domain of the link to another domain, the library helps with privacy. It can be used to change the domain of sites that do not care about privacy to another that does.

TheAwiteb 2 Mar 28, 2022
A generic Rust based Bigtable connection library implemented using gRPC

A generic Rust based Bigtable connection library refactored out the solana mono-repo so that can be shared for different applications.

Lijun Wang 3 Sep 25, 2022
A high performance/low-overhead OpenMetrics library for Rust

* * * EXPERIMENTAL * * * discreet-metrics A high-performance/low-overhead metrics library aiming to conform with OpenMetrics and to satisfy the follow

null 2 Sep 14, 2022
A library for writing type-safe Durable Objects in Rust.

do-proxy A library for writing type-safe Durable Objects (DOs) in Rust. With do-proxy you can: Easily write type-safe APIs for Durable Objects. Abstra

Fisher Darling 12 Dec 4, 2022
📡 Rust mDNS library designed with user interfaces in mind

?? Searchlight Searchlight is an mDNS server & client library designed to be simple, lightweight and easy to use, even if you just have basic knowledg

William 5 Jan 8, 2023
This is a UPnP client library for Rust.

UPnP Client This is a UPNP client library for Rust. Usage Add this to your Cargo.toml: [dependencies] upnp-client = "0.1" Example This example will pr

Tsiry Sandratraina 7 Feb 20, 2023
An async, user-friendly Let's Encrypt/ACMEv2 library written in Rust

lers An async, user-friendly Let's Encrypt/ACMEv2 library written in Rust. The API and implementation were inspired by acme2, acme-micro, and lego. Fe

Alexander Krantz 20 Apr 3, 2023