|
import {promises as fs} from 'fs' |
|
import {once} from 'events' |
|
|
|
import Libp2p from 'libp2p' |
|
import Mplex from 'libp2p-mplex' |
|
import Peer from 'peer-id' |
|
import PeerInfo from 'peer-info' |
|
import Secio from 'libp2p-secio' |
|
import Websockets from 'libp2p-websockets' |
|
import pipe from 'it-pipe' |
|
|
|
async function initPeer(peerJson = 'peer.json') { |
|
const raw = await fs.readFile(peerJson, 'utf8') |
|
return Peer.createFromJSON(JSON.parse(raw)) |
|
} |
|
|
|
export default async function main() { |
|
const serverPeer = await initPeer('server.json') |
|
console.log( |
|
'Peer id', serverPeer.toJSON().id |
|
) |
|
|
|
const serverInfo = new PeerInfo(serverPeer) |
|
serverInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/8080/ws') |
|
serverInfo.protocols.add('/chat/1.0.0') |
|
|
|
const node = await Libp2p.create({ |
|
peerInfo: serverInfo, |
|
modules: { |
|
transport: [Websockets], |
|
connEncryption: [Secio], |
|
streamMuxer: [Mplex], |
|
}, |
|
}) |
|
|
|
node.handle('/chat/1.0.0', ({protocol, stream}) => { |
|
console.log(protocol) |
|
handleChatStream(stream) |
|
.catch(error => { |
|
console.error('%s [error]:', protocol, error) |
|
}) |
|
}) |
|
|
|
await node.start() |
|
await once(process, 'SIGINT') |
|
await node.stop() |
|
|
|
console.log('Bye!') |
|
} |
|
|
|
async function handleChatStream(stream) { |
|
for await (const chunk of pipe( |
|
stream, |
|
fromBufferList, |
|
toString(), |
|
)) { |
|
console.log(chunk) |
|
} |
|
|
|
console.log('DONE') |
|
} |
|
|
|
async function * fromBufferList(source) { |
|
for await (const list of source) { |
|
for (const item of list._bufs) { |
|
yield item |
|
} |
|
} |
|
} |
|
|
|
function toString(encoding = 'utf8') { |
|
return async function * toString(source) { |
|
const decoder = new TextDecoder(encoding) |
|
for await (const chunk of source) { |
|
const string = decoder.decode(chunk, { |
|
stream: true, |
|
}) |
|
if (string.length) { |
|
yield string |
|
} |
|
} |
|
|
|
yield decoder.decode() |
|
} |
|
} |