From 32cb59fa1864d286ff485a1e255fa19ed25b20d8 Mon Sep 17 00:00:00 2001 From: David Dias Date: Thu, 6 Jul 2017 14:26:20 +0100 Subject: [PATCH] docs(examples): transports 1 --- README.md | 7 ++- examples/transports/1.js | 32 ++++++++++ examples/transports/2.js | 0 examples/transports/README.md | 106 ++++++++++++++++++++++++++++++++++ package.json | 4 +- src/index.js | 4 +- 6 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 examples/transports/1.js create mode 100644 examples/transports/2.js create mode 100644 examples/transports/README.md diff --git a/README.md b/README.md index 67bfa31c..25ca9e05 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ - [Bundles](#bundles) - [Usage](#usage) - [Install](#install) + - [Usage](#usage) - [API](#api) - [Development](#development) - [Tests](#tests) @@ -46,7 +47,7 @@ We are in the process of writting better documentation, blog posts, tutorials an - [libp2p.io](https://libp2p.io) - [Specification (WIP)](https://github.com/libp2p/specs) - Talks - - [`libp2p <3 ethereum` at DEVCON2](https://ethereumfoundation.org/devcon/?session=libp2p) [video](https://www.youtube.com/watch?v=HxueJbeMVG4) [slides](https://ethereumfoundation.org/devcon/wp-content/uploads/2016/10/libp2p-HEART-devp2p-IPFS-PLUS-Ethereum-networking.pdf) [demo-1](https://ethereumfoundation.org/devcon/wp-content/uploads/2016/10/libp2p_demo1-1.mp4) [demo-2](https://ethereumfoundation.org/devcon/wp-content/uploads/2016/10/libp2p_demo2-1.mp4) + - [`libp2p <3 ethereum` at DEVCON2](https://ethereumfoundation.org/devcon/?session=libp2p) [📼 video](https://www.youtube.com/watch?v=HxueJbeMVG4) [slides](https://ethereumfoundation.org/devcon/wp-content/uploads/2016/10/libp2p-HEART-devp2p-IPFS-PLUS-Ethereum-networking.pdf) [📼 demo-1](https://ethereumfoundation.org/devcon/wp-content/uploads/2016/10/libp2p_demo1-1.mp4) [📼 demo-2](https://ethereumfoundation.org/devcon/wp-content/uploads/2016/10/libp2p_demo2-1.mp4) - Articles - [The overview of libp2p](https://github.com/libp2p/libp2p#description) @@ -71,6 +72,10 @@ npm install --save libp2p ## Usage +### [Tutorials and Examples](/examples) + +You can find multiple examples on the [examples folder](/examples) that will guide you through using libp2p for several scenarions. + ### Extending libp2p skeleton libp2p becomes very simple and basically acts as a glue for every module that compose this library. Since it can be highly customized, it requires some setup. What we recommend is to have a libp2p build for the system you are developing taking into account in your needs (e.g. for a browser working version of libp2p that acts as the network layer of IPFS, we have a built and minified version that browsers can require). diff --git a/examples/transports/1.js b/examples/transports/1.js new file mode 100644 index 00000000..f7bb6a67 --- /dev/null +++ b/examples/transports/1.js @@ -0,0 +1,32 @@ +'use strict' + +const libp2p = require('libp2p') +const TCP = require('libp2p-tcp') +const PeerInfo = require('peer-info') +const waterfall = require('async/waterfall') + +class MyBundle extends libp2p { + constructor (peerInfo) { + const modules = { + transport: [new TCP()] + } + super(modules, peerInfo) + } +} + +let node + +waterfall([ + (cb) => PeerInfo.create(cb), + (peerInfo, cb) => { + peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0') + node = new MyBundle(peerInfo) + node.start(cb) + } +], (err) => { + if (err) { throw err } + + console.log('node has started (true/false):', node.isOn()) + console.log('listening on:') + node.peerInfo.multiaddrs.forEach((ma) => console.log(ma.toString())) +}) diff --git a/examples/transports/2.js b/examples/transports/2.js new file mode 100644 index 00000000..e69de29b diff --git a/examples/transports/README.md b/examples/transports/README.md new file mode 100644 index 00000000..fc5e4293 --- /dev/null +++ b/examples/transports/README.md @@ -0,0 +1,106 @@ +# [Transports](http://libp2p.io/implementations/#transports) + +libp2p doesn't make assumptions for you, instead, it enables you as the developer of the application to pick the modules you need to run your application, which can vary depending on the runtime you are executing. A libp2p node can use one or more Transports to dial and listen for Connections. These transports are modules that offer a clean interface for dialing and listening, defined by the [interface-transport](https://github.com/libp2p/interface-transport) specification. Some examples of possible transports are: TCP, UTP, WebRTC, QUIC, HTTP, Pigeon and so on. + +A more complete definition of what is a transport can be found on the [interface-transport](https://github.com/libp2p/interface-transport) specification. A way to recognize a candidate transport is through the badge: + +[![](https://raw.githubusercontent.com/diasdavid/interface-transport/master/img/badge.png)](https://raw.githubusercontent.com/diasdavid/interface-transport/master/img/badge.png) + +## 1. Creating a libp2p Bundle with TCP + +When using libp2p, you always want to create your own libp2p Bundle, that is, pick your set of modules and create your network stack with the properties you need. In this example, we will create a bundle with TCP. You can find the complete solution on the file [1.js](/1.js). + +You will need 4 deps total, so go ahead and install all of them with: + +``` +> npm install libp2p libp2p-tcp peer-info async +``` + +Then, on your favorite text editor create a file with the `.js` extension. I've called mine `1.js`. + +First thing is to create our own bundle! Insert: + +```JavaScript +'use strict' + +const libp2p = require('libp2p') +const TCP = require('libp2p-tcp') +const PeerInfo = require('peer-info') +const waterfall = require('async/waterfall') + +// This MyBundle class is your libp2p bundle packed with TCP +class MyBundle extends libp2p { + constructor (peerInfo) { + // modules is a JS object that will describe the components + // we want for our libp2p bundle + const modules = { + transport: [new TCP()] + } + super(modules, peerInfo) + } +} +``` + +Now that we have our own MyBundle class that extends libp2p, let's create a node with it. We will use `async/waterfall` just for code structure, but you don't need to. Append to the same file: + +```JavaScript +let node + +waterfall([ + // First we create a PeerInfo object, which will pack the + // info about our peer. Creating a PeerInfo is an async + // operation because we use the WebCrypto API + // (yeei Universal JS) + (cb) => PeerInfo.create(cb), + (peerInfo, cb) => { + // To signall the addresses we want to be available, we use + // the multiaddr format, a self describable address + peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0') + // Now we can create a node with that PeerInfo object + node = new MyBundle(peerInfo) + // Last, we start the node! + node.start(cb) + } +], (err) => { + if (err) { throw err } + + // At this point the node has started + console.log('node has started (true/false):', node.isOn()) + // And we can print the now listening addresses. + // If you are familiar with TCP, you might have noticed + // that we specified the node to listen in 0.0.0.0 and port + // 0, which means "listen in any network interface and pick + // a port for me + console.log('listening on:') + node.peerInfo.multiaddrs.forEach((ma) => console.log(ma.toString())) +}) +``` + +Running this should result in somehting like: + +```bash +> node 1.js +node has started (true/false): true +listening on: +/ip4/127.0.0.1/tcp/61329/ipfs/QmW2cKTakTYqbQkUzBTEGXgWYFj1YEPeUndE1YWs6CBzDQ +/ip4/192.168.2.156/tcp/61329/ipfs/QmW2cKTakTYqbQkUzBTEGXgWYFj1YEPeUndE1YWs6CBzDQ +``` + +That `QmW2cKTakTYqbQkUzBTEGXgWYFj1YEPeUndE1YWs6CBzDQ` is the PeerId that was created during the PeerInfo generation. + +## 2. Dialing from one node to another node + +Now that we have our bundle, let's create two nodes and make them dial to each other! You can find the complete solution at [2.js](/2.js). + + + +## 3. Using multiple transports + +- show TCP + websockets + +## 4. How to create a new libp2p transport + +- interface-transport +- follow the interface +- show other examples (webrtc, utp, udt (wip), etc) +- diff --git a/package.json b/package.json index f65862d2..c9c39386 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "libp2p", "version": "0.10.0", - "description": "JavaScript Skeleton for libp2p bundles", + "description": "JavaScript base class for libp2p bundles", "main": "src/index.js", "scripts": { "test": "gulp test", @@ -79,4 +79,4 @@ "greenkeeperio-bot ", "mayerwin " ] -} \ No newline at end of file +} diff --git a/src/index.js b/src/index.js index b9a09dcf..8a25710d 100644 --- a/src/index.js +++ b/src/index.js @@ -33,7 +33,7 @@ class Node extends EventEmitter { this.swarm = new Swarm(this.peerInfo, this.peerBook) // Attach stream multiplexers - if (this.modules.connection.muxer) { + if (this.modules.connection && this.modules.connection.muxer) { let muxers = this.modules.connection.muxer muxers = Array.isArray(muxers) ? muxers : [muxers] muxers.forEach((muxer) => this.swarm.connection.addStreamMuxer(muxer)) @@ -54,7 +54,7 @@ class Node extends EventEmitter { } // Attach crypto channels - if (this.modules.connection.crypto) { + if (this.modules.connection && this.modules.connection.crypto) { let cryptos = this.modules.connection.crypto cryptos = Array.isArray(cryptos) ? cryptos : [cryptos] cryptos.forEach((crypto) => {