mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-06-25 23:11:35 +00:00
refactor(docs): async await version of examples/chat (#482)
* 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 example chat * fix: move handler before start * fix: examples readme typos (#481) * fix: simplify libp2p bundle for echo example * chore: remove unused vars
This commit is contained in:
@ -4,76 +4,44 @@
|
||||
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 Pushable = require('pull-pushable')
|
||||
const p = Pushable()
|
||||
let idListener
|
||||
const { stdinToStream, streamToConsole } = require('./stream')
|
||||
|
||||
async.parallel([
|
||||
(callback) => {
|
||||
PeerId.createFromJSON(require('./peer-id-dialer'), (err, idDialer) => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
callback(null, idDialer)
|
||||
})
|
||||
},
|
||||
(callback) => {
|
||||
PeerId.createFromJSON(require('./peer-id-listener'), (err, idListener) => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
callback(null, idListener)
|
||||
})
|
||||
}
|
||||
], (err, ids) => {
|
||||
if (err) throw err
|
||||
const peerDialer = new PeerInfo(ids[0])
|
||||
async function run() {
|
||||
const [idDialer, idListener] = await Promise.all([
|
||||
PeerId.createFromJSON(require('./peer-id-dialer')),
|
||||
PeerId.createFromJSON(require('./peer-id-listener'))
|
||||
])
|
||||
|
||||
// Create a new libp2p node on localhost with a randomly chosen port
|
||||
const peerDialer = new PeerInfo(idDialer)
|
||||
peerDialer.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
|
||||
const nodeDialer = new Node({
|
||||
peerInfo: peerDialer
|
||||
})
|
||||
|
||||
const peerListener = new PeerInfo(ids[1])
|
||||
idListener = ids[1]
|
||||
// Create a PeerInfo with the listening peer's address
|
||||
const peerListener = new PeerInfo(idListener)
|
||||
peerListener.multiaddrs.add('/ip4/127.0.0.1/tcp/10333')
|
||||
nodeDialer.start((err) => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
|
||||
// Start the libp2p host
|
||||
await nodeDialer.start()
|
||||
|
||||
// Output this node's address
|
||||
console.log('Dialer ready, listening on:')
|
||||
|
||||
peerListener.multiaddrs.forEach((ma) => {
|
||||
console.log(ma.toString() + '/p2p/' + idListener.toB58String())
|
||||
})
|
||||
|
||||
nodeDialer.dialProtocol(peerListener, '/chat/1.0.0', (err, conn) => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
console.log('nodeA dialed to nodeB on protocol: /chat/1.0.0')
|
||||
console.log('Type a message and see what happens')
|
||||
// Write operation. Data sent as a buffer
|
||||
pull(
|
||||
p,
|
||||
conn
|
||||
)
|
||||
// Sink, data converted from buffer to utf8 string
|
||||
pull(
|
||||
conn,
|
||||
pull.map((data) => {
|
||||
return data.toString('utf8').replace('\n', '')
|
||||
}),
|
||||
pull.drain(console.log)
|
||||
)
|
||||
// Dial to the remote peer (the "listener")
|
||||
const { stream } = await nodeDialer.dialProtocol(peerListener, '/chat/1.0.0')
|
||||
|
||||
process.stdin.setEncoding('utf8')
|
||||
process.openStdin().on('data', (chunk) => {
|
||||
var data = chunk.toString()
|
||||
p.push(data)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
console.log('Dialer dialed to listener on protocol: /chat/1.0.0')
|
||||
console.log('Type a message and see what happens')
|
||||
|
||||
// Send stdin to the stream
|
||||
stdinToStream(stream)
|
||||
// Read the stream and output to console
|
||||
streamToConsole(stream)
|
||||
}
|
||||
|
||||
run()
|
||||
|
@ -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 = {
|
||||
@ -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 ]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,53 +4,38 @@
|
||||
const PeerId = require('peer-id')
|
||||
const PeerInfo = require('peer-info')
|
||||
const Node = require('./libp2p-bundle.js')
|
||||
const pull = require('pull-stream')
|
||||
const Pushable = require('pull-pushable')
|
||||
const p = Pushable()
|
||||
const { stdinToStream, streamToConsole } = require('./stream')
|
||||
|
||||
PeerId.createFromJSON(require('./peer-id-listener'), (err, idListener) => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
async function run() {
|
||||
// Create a new libp2p node with the given multi-address
|
||||
const idListener = await PeerId.createFromJSON(require('./peer-id-listener'))
|
||||
const peerListener = new PeerInfo(idListener)
|
||||
peerListener.multiaddrs.add('/ip4/0.0.0.0/tcp/10333')
|
||||
const nodeListener = new Node({
|
||||
peerInfo: peerListener
|
||||
})
|
||||
|
||||
nodeListener.start((err) => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
|
||||
// Log a message when a remote peer connects to us
|
||||
nodeListener.on('peer:connect', (peerInfo) => {
|
||||
console.log(peerInfo.id.toB58String())
|
||||
})
|
||||
|
||||
nodeListener.handle('/chat/1.0.0', (protocol, conn) => {
|
||||
pull(
|
||||
p,
|
||||
conn
|
||||
)
|
||||
|
||||
pull(
|
||||
conn,
|
||||
pull.map((data) => {
|
||||
return data.toString('utf8').replace('\n', '')
|
||||
}),
|
||||
pull.drain(console.log)
|
||||
)
|
||||
|
||||
process.stdin.setEncoding('utf8')
|
||||
process.openStdin().on('data', (chunk) => {
|
||||
var data = chunk.toString()
|
||||
p.push(data)
|
||||
})
|
||||
// Handle messages for the protocol
|
||||
await nodeListener.handle('/chat/1.0.0', async ({ stream }) => {
|
||||
// Send stdin to the stream
|
||||
stdinToStream(stream)
|
||||
// Read the stream and output to console
|
||||
streamToConsole(stream)
|
||||
})
|
||||
|
||||
// Start listening
|
||||
await nodeListener.start()
|
||||
|
||||
// Output listen addresses to the console
|
||||
console.log('Listener ready, listening on:')
|
||||
peerListener.multiaddrs.forEach((ma) => {
|
||||
console.log(ma.toString() + '/p2p/' + idListener.toB58String())
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
run()
|
||||
|
40
examples/chat/src/stream.js
Normal file
40
examples/chat/src/stream.js
Normal file
@ -0,0 +1,40 @@
|
||||
'use strict'
|
||||
/* eslint-disable no-console */
|
||||
|
||||
const pipe = require('it-pipe')
|
||||
const lp = require('it-length-prefixed')
|
||||
|
||||
function stdinToStream(stream) {
|
||||
// Read utf-8 from stdin
|
||||
process.stdin.setEncoding('utf8')
|
||||
pipe(
|
||||
// Read from stdin (the source)
|
||||
process.stdin,
|
||||
// Encode with length prefix (so receiving side knows how much data is coming)
|
||||
lp.encode(),
|
||||
// Write to the stream (the sink)
|
||||
stream.sink
|
||||
)
|
||||
}
|
||||
|
||||
function streamToConsole(stream) {
|
||||
pipe(
|
||||
// Read from the stream (the source)
|
||||
stream.source,
|
||||
// Decode length-prefixed data
|
||||
lp.decode(),
|
||||
// Sink function
|
||||
async function (source) {
|
||||
// For each chunk of data
|
||||
for await (const msg of source) {
|
||||
// Output the data as a utf8 string
|
||||
console.log('> ' + msg.toString('utf8').replace('\n', ''))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
stdinToStream,
|
||||
streamToConsole
|
||||
}
|
Reference in New Issue
Block a user