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
110
111
112
113
114
115
116
117
118
//! 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::{CloseGuard, ConnectionRequest, ConnectionStats, Error, Event, InitMessage,
                 Message, Node, NodeId, NodeStats};