Giter VIP home page Giter VIP logo

nanomsg.rs's Introduction

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.

nanomsg.rs's People

Contributors

alexandermorozov avatar bfops avatar blabaere avatar buster avatar danburkert avatar dcbishop avatar dkhenry avatar drawlerr avatar forgerpl avatar ggist avatar gilnaa avatar glycerine avatar jan-schreib avatar musitdev avatar mystal avatar polyfractal avatar purew avatar rschifflin avatar ryman avatar schniz avatar thehydroimpulse avatar tkanakamalla avatar tmccombs avatar vks avatar wdv4758h avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nanomsg.rs's Issues

Move to Cargo

Cargo is now usable as a dependency manager. I've been waiting for this before updating the library further.

Any simple examples?

I'm learning Rust and I'd really like to learn it along with nanomsg. Do you have any simple examples to share?

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.

Official package on cargo registry

I'll be pushing up this package (and libnanomsg) once Cargo supports multiple different sources or when all our deps are on cargo before hand.

This will be the starting point of following semver.

Change assert style

Some asserts follow the assert!(a == b) which should be replaced with the proper assert_eq!(a, b)

Enhance error handling

The native nanomsg lib has quite a lot of constants for the errors, and they should be reported to the nanomsg.rs users. The nn_errno and nn_strerror should be used internally to produce usable results.

Is it possible to not buffer received messages and only hold onto the last one that was received?

I'm working on a real-time AV app with a friend (I send audio data, he receives it and maps it to visuals). It seems that the receiving end is buffering each of the messages ensuring that every single message that was sent is being processed, however we would prefer that the receiver only stored the last message that was received (rather than buffering all of them) - is this possible with nanomsg? Any help appreciated :)

Upgrade nanomsg to version 0.5

The 0.5 version has been out for a a couple of weeks now.
This should just be a matter of changing the version in the root dir Makefile.

Add a NanoResult

Add a NanoResult type:

type NanoResult<T> = Result<T, NanoErr>

Problem with Endpoint lifetime

The rust nightly build cc19e3380 2014-12-20 introduced the warning reproduced below.
This drew my attention to the fact this conflicting lifetime name wasn't even used in the function !
So after resolving the name conflict, I changed the signature parameter to actually use that named lifetime but this had the effect of breaking almost all unit tests !!! 💥

With this modification, it becomes impossible to retrieve the endpoint and then to send or receive a message. For example you can use test_bind alone, but not test_bind and then test_write.
Calling directly bind without storing the result in variable and then write works fine.
Storing the NanoResult or the Endpoint will cause a compilation error.

cannot borrow push_socket as mutable more than once at a time.

It looks like constraining the lifetime of the Endpoint to the one of the Socket makes the Endpoint a 'borrower' of the Socket.

I will post something on reddit and add the link here when done.

Signature before and after the change:
fn bind<'b, 'a: 'b>(&mut self, addr: &str) -> NanoResult<Endpoint<'b>>
fn bind<'b, 'x: 'b>(&'x mut self, addr: &str) -> NanoResult<Endpoint<'b>>
Warning:
   Compiling nanomsg v0.3.0 (file:///home/travis/build/thehydroimpulse/nanomsg.rs)
/home/travis/build/thehydroimpulse/nanomsg.rs/src/lib.rs:203:21: 203:23 warning: lifetime name `'a` shadows another lifetime name that is already in scope
/home/travis/build/thehydroimpulse/nanomsg.rs/src/lib.rs:203     pub fn bind<'b, 'a: 'b>(&mut self, addr: &str) -> NanoResult<Endpoint<'b>> {
                                                                                 ^~
/home/travis/build/thehydroimpulse/nanomsg.rs/src/lib.rs:123:6: 123:8 help: shadowed lifetime `'a` declared here
/home/travis/build/thehydroimpulse/nanomsg.rs/src/lib.rs:123 impl<'a> Socket<'a> {
                                                                  ^~
/home/travis/build/thehydroimpulse/nanomsg.rs/src/lib.rs:203:21: 203:23 help: shadowed lifetimes are deprecated and will become a hard error before 1.0

Consider removing link-config

If we want to be compatible with the stable Rust 1.0, we won't be able to depend on or use syntax extensions, which link-config is composed of. Not to mention it's breaking every other day because of the compiler churn.

Idiomatic Folders

Should add a src and examples folder along with the traditional lib.rs and bin.rs files.

Multi-threading

I haven't been able to dig down into it but I want to figure out a way we can get this library to be multi-threaded. As far as I can tell, we aren't using threads/tasks at all in the tests anymore. Nanomsg in theory should be thread-safe (and that was one of the original goals versus something like ZeroMQ where it was strictly thread-unsafe.

build problem

does this project to track the latest rust version?

Split The FFI

The FFI should be placed within it's own module/file: ffi.rs

Stability Attributes

We should mark each function with a stability attribute. Most of them, if not all, will receive the #[unstable] attribute.

Fix broken build

Some recent changes in the parser/syntax has lead to link-config breaking. Should be a pretty easy fix.

to_raw method on Protocol

We should have a .to_raw method on the Protocol instead of doing it within the Socket::new method.

Rust 1.0 and nanomsg.rs master branch

Since some public parts (Reader, Writer, Duration ...) of nanomsg.rs won't make it in Rust 1.0, we will probably end up with a branch for the Rust 1.0 and another one for Rust nightly.
@thehydroimpulse Which one should be the master ?

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?

Refactor

A meta-issue for the refactor of this library that will focus on a few main things:

  • A safe idiomatic Rust API
  • A separate, low-level package containing only the bindings to nanomsg.
  • Lots and lots of tests!

Right now, the library is fairly ugly, with barely any tests, super non-idiomatic and most likely unsafe to use.

Todo:

  • #28 Create a new package libnanomsg for the bindings.
  • Create some basic tests to ensure the bindings work correctly and we're not segfaulting or anything.
  • Create a result module that will contain the new NanoResult and NanoError types.
  • Create a socket module that will be the high-level API for working with nanomsg sockets.
  • Create a protocol module that will hold a Protocol enum with the various different protocols.

Some ideas for the socket API:

use nanomsg::{Socket, Req, Rep};

spawn(proc() {
    let mut socket = match Socket::new(Rep) {
        Ok(socket) => socket,
        Err(err) => fail!("{}", err)
    };

    match socket.bind("tcp://*:6789") {
        Ok(()) => {},
        Err(err) => fail!("{}", err)
    }

    socket.read();   
});

let mut client = Socket::new(Req);
client.bind("tcp://*:6789");
client.send("shutdown");

FFI Package

The FFI should be isolated to a separate package within this repo. That'll allow those who just want the raw bindings can just grab those. The main package will then be a higher-level, Rust idiomatic wrapper that'll make it dead simple to get going!

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

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.

Documentation

A Jekyll site along with a rustdoc for the API would be pretty slick.

The jekyll site would simply have an introduction to using the library and more of the higher-level concepts rather than low-level API usage.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.