1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
//! A networking layer based on MessagePack messages.
//!
//! This crate provides an abstraction layer above TCP that uses
//! [MessagePack](http://www.msgpack.org) encoded messages instead of pure byte streams.
//! It also abstracts from addresses and connections and instead uses node identifiers to
//! distinguish and address nodes.
//!
//! The main struct of this crate is [`Node`](struct.Node.html) which can be parametrized:
//!
//! * [`Message`](trait.Message.html) - The nodes using this crate communicate via messages that
//! conform to the `Message` trait. These messages are serialized using `serde` to the
//! efficient MessagePack format.
//!
//! * [`NodeId`](trait.NodeId.html) - This crate identifies and distinguishes nodes based on their
//! `NodeId`. It is required that all communicating nodes have different ids.
//! Therefore the node ids should be unique. This can be achieved by using the IP address and port
//! number of the main listening socket. Alternatively, a large random number can be used (128 bit
//! should be enough to expect uniqueness).
//!
//! * [`InitMessage`](trait.InitMessage.html) - The first message exchanged on all connections uses
//! the `InitMessage` trait instead of `Message`.
//!
//! # Low-level protocol
//! When establishing a new connection (either incoming or outgoing), first an `InitMessage` is
//! sent to the remote node together with the local `NodeId` and then the initialization message
//! and the remote `NodeId` is read from that node.
//! After inspecting the initialization message, the connection is either rejected and closed or
//! accepted and added to the connection registry.
//!
//! When established, the connection can be used to send multiple messages of the `Message` type.
//!
//! When idle for a certain timeout or when closing the node by dropping its
//! [`CloseGuard`](struct.CloseGuard.html), the connection is closed.
//!
//! # Examples
//! To use this crate, first a [`Node`](struct.Node.html) has to be created with a node id and an
//! initialization message which are sent to other nodes as first message.
//!
//! ```
//! use msgpacknet::*;
//! let node = Node::<String, (u64, u64)>::create_default();
//! ```
//!
//! Then, sockets can be opened for listening and accepting connections.
//! The method [`node.listen_defaults()`](struct.Node.html#method.listen_defaults) can be used to
//! listen on free ports on IPv4 and IPv6.
//!
//! ```
//! # use msgpacknet::*;
//! # let node = Node::<String, (u64, u64)>::create_default();
//! node.listen_defaults().expect("Failed to bind");
//! ```
//!
//! The actual addresses can be obtained using
//! [`node.addresses()`](struct.Node.html#method.addresses).
//!
//! ```
//! # use msgpacknet::*;
//! # let node = Node::<String, (u64, u64)>::create_default();
//! # node.listen_defaults().expect("Failed to bind");
//! println!("Addresses: {:?}", node.addresses());
//! let addr = node.addresses()[0];
//! ```
//!
//! Connections to other nodes can be established via
//! [`connect(...)`](struct.Node.html#method.connect). The result of the call is the remote side's
//! node id.
//!
//! ```
//! # use msgpacknet::*;
//! # let node = Node::<String, (u64, u64)>::create_default();
//! # node.listen_defaults().expect("Failed to bind");
//! # let addr = node.addresses()[0];
//! let peer_id = node.connect(addr).expect("Failed to connect");
//! ```
//!
//! Then, messages can be sent via [`send(...)`](struct.Node.html#method.send)...
//!
//! ```
//! # use msgpacknet::*;
//! # let node = Node::<String, (u64, u64)>::create_default();
//! # let peer_id = node.node_id();
//! let msg = "Hello world".to_owned();
//! node.send(&peer_id, &msg).expect("Failed to send");
//! ```
//!
//! ...and received via [`receive()`](struct.Node.html#method.receive).
//!
//! ```
//! # use msgpacknet::*;
//! # let node = Node::<(), (u64, u64)>::create_default();
//! # node.send(&node.node_id(), &()).expect("Failed to send");
//! let event = node.receive();
//! ```

// This crate is targeted for Rust 1.4 stable

extern crate serde;
extern crate rmp_serde;
extern crate net2;
extern crate time;
extern crate rand;

mod stats;
mod queue;
mod socket;
#[cfg(test)] mod tests;

pub use socket::{Event, ConnectionRequest, CloseGuard, NodeStats, ConnectionStats, Node, Message, InitMessage, NodeId, Error};