Skip to content

Commit

Permalink
Merge pull request #84 from tomaka/websockets
Browse files Browse the repository at this point in the history
Add a websocket transport
  • Loading branch information
tomaka committed Jan 15, 2018
2 parents f45cd87 + 6c737c6 commit b83ebe3
Show file tree
Hide file tree
Showing 12 changed files with 756 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -9,6 +9,7 @@ members = [
"libp2p-secio",
"libp2p-swarm",
"libp2p-tcp-transport",
"libp2p-websocket",
"multistream-select",
"datastore",
"futures-mutex",
Expand Down
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -25,6 +25,7 @@ Architecture of the crates of this repository:
`ConnectionUpgrade` trait of `libp2p-swarm`.
- `libp2p-swarm`: Core library that contains all the traits of *libp2p* and plugs things together.
- `libp2p-tcp-transport`: Implementation of the `Transport` trait of `libp2p-swarm` for TCP/IP.
- `libp2p-websocket`: Implementation of the `Transport` trait of `libp2p-swarm` for Websockets.
- `multistream-select`: Implementation of the `multistream-select` protocol, which is used to
negotiate a protocol over a newly-established connection with a peer, or after a connection
upgrade.
Expand Down
1 change: 1 addition & 0 deletions example/Cargo.toml
Expand Up @@ -10,5 +10,6 @@ multiplex = { path = "../multiplex-rs" }
libp2p-secio = { path = "../libp2p-secio" }
libp2p-swarm = { path = "../libp2p-swarm" }
libp2p-tcp-transport = { path = "../libp2p-tcp-transport" }
libp2p-websocket = { path = "../libp2p-websocket" }
tokio-core = "0.1"
tokio-io = "0.1"
7 changes: 7 additions & 0 deletions example/examples/echo-dialer.rs
Expand Up @@ -23,6 +23,7 @@ extern crate futures;
extern crate libp2p_secio as secio;
extern crate libp2p_swarm as swarm;
extern crate libp2p_tcp_transport as tcp;
extern crate libp2p_websocket as websocket;
extern crate multiplex;
extern crate tokio_core;
extern crate tokio_io;
Expand All @@ -34,6 +35,7 @@ use swarm::{UpgradeExt, SimpleProtocol, Transport, DeniedConnectionUpgrade};
use tcp::TcpConfig;
use tokio_core::reactor::Core;
use tokio_io::codec::length_delimited;
use websocket::WsConfig;

fn main() {
// Determine which address to dial.
Expand All @@ -46,6 +48,11 @@ fn main() {
// We start by creating a `TcpConfig` that indicates that we want TCP/IP.
let transport = TcpConfig::new(core.handle())

// In addition to TCP/IP, we also want to support the Websockets protocol on top of TCP/IP.
// The parameter passed to `WsConfig::new()` must be an implementation of `Transport` to be
// used for the underlying multiaddress.
.or_transport(WsConfig::new(TcpConfig::new(core.handle())))

// On top of TCP/IP, we will use either the plaintext protocol or the secio protocol,
// depending on which one the remote supports.
.with_upgrade({
Expand Down
6 changes: 6 additions & 0 deletions example/examples/echo-server.rs
Expand Up @@ -23,6 +23,7 @@ extern crate futures;
extern crate libp2p_secio as secio;
extern crate libp2p_swarm as swarm;
extern crate libp2p_tcp_transport as tcp;
extern crate libp2p_websocket as websocket;
extern crate multiplex;
extern crate tokio_core;
extern crate tokio_io;
Expand All @@ -34,6 +35,7 @@ use swarm::{Transport, UpgradeExt, SimpleProtocol};
use tcp::TcpConfig;
use tokio_core::reactor::Core;
use tokio_io::codec::length_delimited;
use websocket::WsConfig;

fn main() {
// Determine which address to listen to.
Expand All @@ -45,6 +47,10 @@ fn main() {
// Now let's build the transport stack.
// We start by creating a `TcpConfig` that indicates that we want TCP/IP.
let transport = TcpConfig::new(core.handle())
// In addition to TCP/IP, we also want to support the Websockets protocol on top of TCP/IP.
// The parameter passed to `WsConfig::new()` must be an implementation of `Transport` to be
// used for the underlying multiaddress.
.or_transport(WsConfig::new(TcpConfig::new(core.handle())))

// On top of TCP/IP, we will use either the plaintext protocol or the secio protocol,
// depending on which one the remote supports.
Expand Down
1 change: 1 addition & 0 deletions libp2p-swarm/src/connection_reuse.rs
Expand Up @@ -199,6 +199,7 @@ where S: Stream<Item = (F, Multiaddr), Error = IoError>,
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
match self.listener.poll() {
Ok(Async::Ready(Some((upgrade, client_addr)))) => {
println!("ready stream");
self.current_upgrades.push((upgrade, client_addr));
}
Ok(Async::NotReady) => (),
Expand Down
21 changes: 21 additions & 0 deletions libp2p-websocket/Cargo.toml
@@ -0,0 +1,21 @@
[package]
name = "libp2p-websocket"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]

[dependencies]
libp2p-swarm = { path = "../libp2p-swarm" }
futures = "0.1"
multiaddr = "0.2.0"
rw-stream-sink = { path = "../rw-stream-sink" }
tokio-io = "0.1"

[target.'cfg(not(target_os = "emscripten"))'.dependencies]
websocket = { version = "0.20.2", default-features = false, features = ["async", "async-ssl"] }

[target.'cfg(target_os = "emscripten")'.dependencies]
stdweb = { version = "0.1.3", default-features = false }

[target.'cfg(not(target_os = "emscripten"))'.dev-dependencies]
libp2p-tcp-transport = { path = "../libp2p-tcp-transport" }
tokio-core = "0.1"
46 changes: 46 additions & 0 deletions libp2p-websocket/README.md
@@ -0,0 +1,46 @@
Implementation of the libp2p `Transport` trait for Websockets.

See the documentation of `swarm` and of libp2p in general to learn how to use the `Transport`
trait.

This library is used in a different way depending on whether you are compiling for emscripten
or for a different operating system.

# Emscripten

On emscripten, you can create a `BrowserWsConfig` object with `BrowserWsConfig::new()`. It can
then be used as a transport.

Listening on a websockets multiaddress isn't supported on emscripten. Dialing a multiaddress
which uses `ws` on top of TCP/IP will automatically use the `XMLHttpRequest` Javascript object.

```rust
use libp2p_websocket::BrowserWsConfig;

let ws_config = BrowserWsConfig::new();
// let _ = ws_config.dial("/ip4/40.41.42.43/tcp/12345/ws".parse().unwrap());
```

# Other operating systems

On other operating systems, this library doesn't open any socket by itself. Instead it must be
plugged on top of another implementation of `Transport` such as TCP/IP.

This underlying transport must be put inside a `WsConfig` object through the
`WsConfig::new()` function.

```rust
extern crate libp2p_swarm;
extern crate libp2p_tcp_transport;
extern crate libp2p_websocket;
extern crate tokio_core;

use libp2p_swarm::{Multiaddr, Transport};
use libp2p_tcp_transport::TcpConfig;
use libp2p_websocket::WsConfig;
use tokio_core::reactor::Core;

let core = Core::new().unwrap();
let ws_config = WsConfig::new(TcpConfig::new(core.handle()));
let _ = ws_config.dial("/ip4/40.41.42.43/tcp/12345/ws".parse().unwrap());
```

0 comments on commit b83ebe3

Please sign in to comment.