Skip to content

Commit

Permalink
refactor(docs): async await version of examples/echo (#483)
Browse files Browse the repository at this point in the history
* fix: performance bottleneck in stat.js (#463)

Array.shift seems to be very slow, perhaps linear, on some
engines, resulting in  _update consuming a lot of CPU.

* docs(fix): correct docs and example for pnet (#464)

* docs(fix): correct docs and example for pnet

* docs(fix): correct pnet docs

* docs(fix): update README.md language (#468)

* docs: reciprocate (#474)

* docs(example): fix ipfs cat (#475)

`ipfs.files.cat` is incorrect. the correct function is `ipfs.cat`

* fix: async await examples/echo

* fix: examples readme typos (#481)

* fix: simplify libp2p bundle for echo example
  • Loading branch information
dirkmc authored and jacobheun committed Nov 27, 2019
1 parent ed75534 commit 3fc352c
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 157 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ We've come a long way, but this project is still in Alpha, lots of development i

## Background

libp2p is the product of a long and arduous quest to understand the evolution of the Internet networking stack. In order to build P2P applications, devs have long had to made custom ad-hoc solutions to fit their needs, sometimes making some hard assumptions about their runtimes and the state of the network at the time of their development. Today, looking back more than 20 years, we see a clear pattern in the types of mechanisms built around the Internet Protocol, IP, which can be found throughout many layers of the OSI layer system, libp2p distils these mechanisms into flat categories and defines clear interfaces that once exposed, enable other protocols and applications to use and swap them, enabling upgradability and adaptability for the runtime, without breaking the API.
libp2p is the product of a long and arduous quest to understand the evolution of the Internet networking stack. In order to build P2P applications, devs have long had to make custom ad-hoc solutions to fit their needs, sometimes making some hard assumptions about their runtimes and the state of the network at the time of their development. Today, looking back more than 20 years, we see a clear pattern in the types of mechanisms built around the Internet Protocol, IP, which can be found throughout many layers of the OSI layer system, libp2p distils these mechanisms into flat categories and defines clear interfaces that once exposed, enable other protocols and applications to use and swap them, enabling upgradability and adaptability for the runtime, without breaking the API.

We are in the process of writing better documentation, blog posts, tutorials and a formal specification. Today you can find:

Expand Down Expand Up @@ -101,7 +101,7 @@ You can find multiple examples on the [examples folder](/examples) that will gui

### Creating your own libp2p bundle

The libp2p module acts as a glue for every libp2p module that you can use to create your own libp2p bundle. Creating your own libp2p bundle gives you a lot of freedom when it comes to customize it with features and default setup. We recommend creating your own libp2p bundle for the app you are developing that takes in account your needs (e.g. for a browser working version of libp2p that acts as the network layer of IPFS, we have a built one that leverages the Browser transports).
The libp2p module acts as a glue for every libp2p module that you can use to create your own libp2p bundle. Creating your own libp2p bundle gives you a lot of freedom when it comes to customize it with features and default setup. We recommend creating your own libp2p bundle for the app you are developing that takes into account your needs (e.g. for a browser working version of libp2p that acts as the network layer of IPFS, we have built one that leverages the Browser transports).

**Example:**

Expand All @@ -122,7 +122,7 @@ const MulticastDNS = require('libp2p-mdns')
const DHT = require('libp2p-kad-dht')
const GossipSub = require('libp2p-gossipsub')
const defaultsDeep = require('@nodeutils/defaults-deep')
const Protector = require('libp2p-pnet')
const Protector = require('libp2p/src/pnet')
const DelegatedPeerRouter = require('libp2p-delegated-peer-routing')
const DelegatedContentRouter = require('libp2p-delegated-content-routing')

Expand Down Expand Up @@ -432,7 +432,7 @@ Returns an object containing the following keys:
- dataSent
- dataReceived

Each one of them contains an object that has a key for each interval (`60000`, `300000` and `900000` miliseconds).
Each one of them contains an object that has a key for each interval (`60000`, `300000` and `900000` milliseconds).

Each one of these values is [an exponential moving-average instance](https://github.com/pgte/moving-average#readme).

Expand All @@ -456,7 +456,7 @@ Returns an object containing the following keys:
dataSent
dataReceived

Each one of them contains an object that has a key for each interval (`60000`, `300000` and `900000` miliseconds).
Each one of them contains an object that has a key for each interval (`60000`, `300000` and `900000` milliseconds).

Each one of these values is [an exponential moving-average instance](https://github.com/pgte/moving-average#readme).

Expand All @@ -481,7 +481,7 @@ Returns an object containing the following keys:
- dataSent
- dataReceived

Each one of them contains an object that has a key for each interval (`60000`, `300000` and `900000` miliseconds).
Each one of them contains an object that has a key for each interval (`60000`, `300000` and `900000` milliseconds).

Each one of these values is [an exponential moving-average instance](https://github.com/pgte/moving-average#readme).

Expand All @@ -506,13 +506,13 @@ Returns an object containing the following keys:
- dataSent
- dataReceived

Each one of them contains an object that has a key for each interval (`60000`, `300000` and `900000` miliseconds).
Each one of them contains an object that has a key for each interval (`60000`, `300000` and `900000` milliseconds).

Each one of these values is [an exponential moving-average instance](https://github.com/pgte/moving-average#readme).

#### Stats update interval

Stats are not updated in real-time. Instead, measurements are buffered and stats are updated at an interval. The maximum interval can be defined through the `Switch` constructor option `stats.computeThrottleTimeout`, defined in miliseconds.
Stats are not updated in real-time. Instead, measurements are buffered and stats are updated at an interval. The maximum interval can be defined through the `Switch` constructor option `stats.computeThrottleTimeout`, defined in milliseconds.

### Private Networks

Expand All @@ -523,15 +523,15 @@ Libp2p provides support for connection protection, such as for private networks.
#### Protectors

Some available network protectors:
* [libp2p-pnet](https://github.com/libp2p/js-libp2p-pnet)
* [libp2p-pnet](https://github.com/libp2p/js-libp2p/tree/master/src/pnet)

## Development

**Clone and install dependencies:**

```sh
> git clone https://github.com/ipfs/js-ipfs.git
> cd js-ipfs
> git clone https://github.com/libp2p/js-libp2p.git
> cd js-libp2p
> npm install
```

Expand Down
6 changes: 4 additions & 2 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# `js-libp2p` Examples and Tutorials

In this folder, you can find a variety of examples to help you get started in using js-libp2p, in Node.js and in the Browser. Every example as a specific purpose and some of each incorporate a full tutorial that you can follow through, helping you expand your knowledge about libp2p and p2p networks in general.
In this folder, you can find a variety of examples to help you get started in using js-libp2p, in Node.js and in the Browser. Every example has a specific purpose and some incorporate a full tutorial that you can follow through, helping you expand your knowledge about libp2p and p2p networks in general.

Let us know if you find any issue or if you want to contribute and add a new tutorial, feel welcome to submit a PR, thank you!
Let us know if you find any issues, or if you want to contribute and add a new tutorial, feel free to submit a PR, thank you!

## Understanding how libp2p works

Expand All @@ -22,3 +22,5 @@ Let us know if you find any issue or if you want to contribute and add a new tut
- Running libp2p in the Electron (future)
- [The standard echo net example with libp2p](./echo)
- [A simple chat app with libp2p](./chat)

For go-libp2p examples, check out https://github.com/libp2p/go-libp2p-examples#examples-and-tutorials
2 changes: 1 addition & 1 deletion examples/delegated-routing/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class App extends Component {
isLoading: this.state.isLoading + 1
})

this.ipfs.files.cat(this.state.hash, (err, data) => {
this.ipfs.cat(this.state.hash, (err, data) => {
if (err) console.log('Error', err)

this.setState({
Expand Down
73 changes: 38 additions & 35 deletions examples/echo/src/dialer.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,54 @@
const PeerId = require('peer-id')
const PeerInfo = require('peer-info')
const Node = require('./libp2p-bundle')
const pull = require('pull-stream')
const async = require('async')
const pipe = require('it-pipe')

async.parallel([
(cb) => PeerId.createFromJSON(require('./id-d'), cb),
(cb) => PeerId.createFromJSON(require('./id-l'), cb)
], (err, ids) => {
if (err) { throw err }
async function run() {
const [dialerId, listenerId] = await Promise.all([
PeerId.createFromJSON(require('./id-d')),
PeerId.createFromJSON(require('./id-l'))
])

// Dialer
const dialerId = ids[0]
const dialerPeerInfo = new PeerInfo(dialerId)
dialerPeerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
const dialerNode = new Node({
peerInfo: dialerPeerInfo
})

// Peer to Dial
const listenerPeerInfo = new PeerInfo(ids[1])
const listenerId = ids[1]
// Peer to Dial (the listener)
const listenerPeerInfo = new PeerInfo(listenerId)
const listenerMultiaddr = '/ip4/127.0.0.1/tcp/10333/p2p/' +
listenerId.toB58String()
listenerPeerInfo.multiaddrs.add(listenerMultiaddr)

dialerNode.start((err) => {
if (err) { throw err }

console.log('Dialer ready, listening on:')
dialerPeerInfo.multiaddrs.forEach((ma) => console.log(ma.toString() +
'/p2p/' + dialerId.toB58String()))

console.log('Dialing to peer:', listenerMultiaddr.toString())
dialerNode.dialProtocol(listenerPeerInfo, '/echo/1.0.0', (err, conn) => {
if (err) { throw err }

console.log('nodeA dialed to nodeB on protocol: /echo/1.0.0')

pull(
pull.values(['hey']),
conn,
pull.collect((err, data) => {
if (err) { throw err }
console.log('received echo:', data.toString())
})
)
})
})
})
// Start the dialer libp2p node
await dialerNode.start()

console.log('Dialer ready, listening on:')
dialerPeerInfo.multiaddrs.forEach((ma) => console.log(ma.toString() +
'/p2p/' + dialerId.toB58String()))

// Dial the listener node
console.log('Dialing to peer:', listenerMultiaddr.toString())
const { stream } = await dialerNode.dialProtocol(listenerPeerInfo, '/echo/1.0.0')

console.log('nodeA dialed to nodeB on protocol: /echo/1.0.0')

pipe(
// Source data
['hey'],
// Write to the stream, and pass its output to the next function
stream,
// Sink function
async function (source) {
// For each chunk of data
for await (const data of source) {
// Output the data
console.log('received echo:', data.toString())
}
}
)
}

run()
54 changes: 2 additions & 52 deletions examples/echo/src/libp2p-bundle.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,12 @@
'use strict'

const TCP = require('libp2p-tcp')
const MulticastDNS = require('libp2p-mdns')
const WS = require('libp2p-websockets')
const Bootstrap = require('libp2p-bootstrap')
const spdy = require('libp2p-spdy')
const KadDHT = require('libp2p-kad-dht')
const mplex = require('libp2p-mplex')
const secio = require('libp2p-secio')
const defaultsDeep = require('@nodeutils/defaults-deep')
const libp2p = require('../../..')

function mapMuxers (list) {
return list.map((pref) => {
if (typeof pref !== 'string') {
return pref
}
switch (pref.trim().toLowerCase()) {
case 'spdy': return spdy
case 'mplex': return mplex
default:
throw new Error(pref + ' muxer not available')
}
})
}

function getMuxers (muxers) {
const muxerPrefs = process.env.LIBP2P_MUXER
if (muxerPrefs && !muxers) {
return mapMuxers(muxerPrefs.split(','))
} else if (muxers) {
return mapMuxers(muxers)
} else {
return [mplex, spdy]
}
}

class Node extends libp2p {
constructor (_options) {
const defaults = {
Expand All @@ -44,29 +15,8 @@ class Node extends libp2p {
TCP,
WS
],
streamMuxer: getMuxers(_options.muxer),
connEncryption: [ secio ],
peerDiscovery: [
MulticastDNS,
Bootstrap
],
dht: KadDHT
},
config: {
peerDiscovery: {
mdns: {
interval: 10000,
enabled: false
},
bootstrap: {
interval: 10000,
enabled: false,
list: _options.bootstrapList
}
},
dht: {
kBucketSize: 20
}
streamMuxer: [ mplex ],
connEncryption: [ secio ]
}
}

Expand Down
57 changes: 26 additions & 31 deletions examples/echo/src/listener.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,34 @@
const PeerId = require('peer-id')
const PeerInfo = require('peer-info')
const Node = require('./libp2p-bundle')
const pull = require('pull-stream')
const series = require('async/series')

let listenerId
let listenerNode

series([
(cb) => {
PeerId.createFromJSON(require('./id-l'), (err, id) => {
if (err) { return cb(err) }
listenerId = id
cb()
})
},
(cb) => {
const listenerPeerInfo = new PeerInfo(listenerId)
listenerPeerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/10333')
listenerNode = new Node({
peerInfo: listenerPeerInfo
})

listenerNode.on('peer:connect', (peerInfo) => {
console.log('received dial to me from:', peerInfo.id.toB58String())
})

listenerNode.handle('/echo/1.0.0', (protocol, conn) => pull(conn, conn))
listenerNode.start(cb)
}
], (err) => {
if (err) { throw err }
const pipe = require('it-pipe')

async function run() {
const listenerId = await PeerId.createFromJSON(require('./id-l'))

// Listener libp2p node
const listenerPeerInfo = new PeerInfo(listenerId)
listenerPeerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/10333')
const listenerNode = new Node({
peerInfo: listenerPeerInfo
})

// Log a message when we receive a connection
listenerNode.on('peer:connect', (peerInfo) => {
console.log('received dial to me from:', peerInfo.id.toB58String())
})

// Handle incoming connections for the protocol by piping from the stream
// back to itself (an echo)
await listenerNode.handle('/echo/1.0.0', ({ stream }) => pipe(stream.source, stream.sink))

// Start listening
await listenerNode.start()

console.log('Listener ready, listening on:')
listenerNode.peerInfo.multiaddrs.forEach((ma) => {
console.log(ma.toString() + '/p2p/' + listenerId.toB58String())
})
})
}

run()
6 changes: 3 additions & 3 deletions examples/pnet-ipfs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

const IPFS = require('ipfs')
const assert = require('assert').strict
const writeKey = require('libp2p-pnet').generate
const { generate: writeKey } = require('libp2p/src/pnet')
const path = require('path')
const fs = require('fs')
const privateLibp2pBundle = require('./libp2p-bundle')
Expand Down Expand Up @@ -117,7 +117,7 @@ const connectAndTalk = async () => {
// Add some data to node 1
let addedCID
try {
addedCID = await node1.files.add(dataToAdd)
addedCID = await node1.add(dataToAdd)
} catch (err) {
return doStop(err)
}
Expand All @@ -126,7 +126,7 @@ const connectAndTalk = async () => {
// Retrieve the data from node 2
let cattedData
try {
cattedData = await node2.files.cat(addedCID[0].path)
cattedData = await node2.cat(addedCID[0].path)
} catch (err) {
return doStop(err)
}
Expand Down
2 changes: 1 addition & 1 deletion examples/pnet-ipfs/libp2p-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const TCP = require('libp2p-tcp')
const MPLEX = require('libp2p-mplex')
const SECIO = require('libp2p-secio')
const fs = require('fs')
const Protector = require('libp2p-pnet')
const Protector = require('libp2p/src/pnet')

/**
* Options for the libp2p bundle
Expand Down
11 changes: 5 additions & 6 deletions examples/pnet-ipfs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@
"author": "",
"license": "ISC",
"dependencies": {
"ipfs": "~0.32.3",
"libp2p": "~0.23.1",
"libp2p-mplex": "~0.8.2",
"libp2p-pnet": "../../",
"libp2p-secio": "~0.10.0",
"libp2p-tcp": "~0.13.0"
"ipfs": "^0.38.0",
"libp2p": "^0.26.2",
"libp2p-mplex": "^0.8.5",
"libp2p-secio": "^0.11.1",
"libp2p-tcp": "^0.13.2"
}
}
Loading

0 comments on commit 3fc352c

Please sign in to comment.