DEV Community

Carlos Galarza
Carlos Galarza

Posted on • Edited on

33 13

Make a P2P connection in 10 minutes

Distributed Network

This is a short guide on how to make a P2P chat. My aim is to give you only a taste if you like I could write a deeper article explaining how all these things work. That said, let's start.

Preparation

The only thing you will need is the latest NodeJS and your favorite editor, mine is Visual Studio Code. Now create a folder for our project, open a command line, initialize an npm repo with npm init and install some libraries we will need with:



npm i --save discovery-swarm dat-swarm-defaults portfinder get-port


Enter fullscreen mode Exit fullscreen mode

Our first P2P connection

Let's start by doing a simple P2P connection, thanks to some great libraries from the Node.js community it is too simple:

const crypto = require('crypto')
const Swarm = require('discovery-swarm')
const defaults = require('dat-swarm-defaults')
const getPort = require('get-port')
const readline = require('readline')
/**
* Here we will save our TCP peer connections
* using the peer id as key: { peer_id: TCP_Connection }
*/
const peers = {}
// Counter for connections, used for identify connections
let connSeq = 0
// Peer Identity, a random hash for identify your peer
const myId = crypto.randomBytes(32)
console.log('Your identity: ' + myId.toString('hex'))
// reference to redline interface
let rl
/**
* Function for safely call console.log with readline interface active
*/
function log () {
if (rl) {
rl.clearLine()
rl.close()
rl = undefined
}
for (let i = 0, len = arguments.length; i < len; i++) {
console.log(arguments[i])
}
askUser()
}
/*
* Function to get text input from user and send it to other peers
* Like a chat :)
*/
const askUser = async () => {
rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
rl.question('Send message: ', message => {
// Broadcast to peers
for (let id in peers) {
peers[id].conn.write(message)
}
rl.close()
rl = undefined
askUser()
});
}
/**
* Default DNS and DHT servers
* This servers are used for peer discovery and establishing connection
*/
const config = defaults({
// peer-id
id: myId,
})
/**
* discovery-swarm library establishes a TCP p2p connection and uses
* discovery-channel library for peer discovery
*/
const sw = Swarm(config)
;(async () => {
// Choose a random unused port for listening TCP peer connections
const port = await getPort()
sw.listen(port)
console.log('Listening to port: ' + port)
/**
* The channel we are connecting to.
* Peers should discover other peers in this channel
*/
sw.join('our-fun-channel')
sw.on('connection', (conn, info) => {
// Connection id
const seq = connSeq
const peerId = info.id.toString('hex')
log(`Connected #${seq} to peer: ${peerId}`)
// Keep alive TCP connection with peer
if (info.initiator) {
try {
conn.setKeepAlive(true, 600)
} catch (exception) {
log('exception', exception)
}
}
conn.on('data', data => {
// Here we handle incomming messages
log(
'Received Message from peer ' + peerId,
'----> ' + data.toString()
)
})
conn.on('close', () => {
// Here we handle peer disconnection
log(`Connection ${seq} closed, peer id: ${peerId}`)
// If the closing connection is the last connection with the peer, removes the peer
if (peers[peerId].seq === seq) {
delete peers[peerId]
}
})
// Save the connection
if (!peers[peerId]) {
peers[peerId] = {}
}
peers[peerId].conn = conn
peers[peerId].seq = seq
connSeq++
})
// Read user message from command line
askUser()
})()
view raw index.js hosted with ❤ by GitHub

Run this code in two consoles and this is it!. Now you can run it in other device right in your LAN and should work even without internet, also you can share and run this script in any other computer or device with internet around the world and it just works, so nice!

How it works?

This code uses the technology behind the Dat Project. All communications are decentralized and work over a P2P network.

...

I love feedback. Ask me questions, comment on your experience with P2P technologies and share your ideas! Thanks for reading :)

This series is possible thanks to the awesome tools delivered by the DatProject, Webtorrent and the NodeJS community.

Follow me on here and on Twitter if you want to know more about tech and distributed P2P networks: https://twitter.com/carloslfu

Reinvent your career. Join DEV.

It takes one minute and is worth it for your career.

Get started

Top comments (14)

Collapse
 
menakalak profile image
menaka lakshan

hi Carlos Galarza this is great as i expected. but i have small problem here. when i run this script on two different computers this will not works as expected. can you plz help me.

Collapse
 
carloslfu profile image
Carlos Galarza

Of course, I will email you.

Collapse
 
daaadyaaar profile image
daaadyaaar

Could you share this concept for me as well, I would like to use your solution between some valid computers IP on the internet or a bigger network.
Thanks

Thread Thread
 
carloslfu profile image
Carlos Galarza

I this code doesn't work for you I recommend you to use dev.to/carloslfu/comment/68ih. You don't need to put the computers IP in the code. Computers are connected with each other using the channel name:

/**
 * The channel we are connecting to.
 * Peers should discover other peers in this channel
 */
sw.join('our-fun-channel-name')

Hope it helps

Thread Thread
 
daaadyaaar profile image
daaadyaaar

Thanks for replying me Carlos.

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
carloslfu profile image
Carlos Galarza

Of course, Rinay, email me with more details or some code I can find a moment to help you. Sorry for the late response I last month I was busy.

Collapse
 
carloslfu profile image
Carlos Galarza

If this implementation sometimes doesn't work is because of some issues with the discovery-swarm library. Fortunately, Hyperswarm was released recently. It implements a more reliable way of doing peer discovery. So, if you are experimenting issues try to use it now, this article pfrazee.hashbase.io/blog/hyperswarm about Hyperswarm includes a code example and here is the GitHub repo with some docs: github.com/hyperswarm/discovery.

Collapse
 
jake profile image
Jake Casto

Great Article! Very brief and got right to the point, loved it. How would you go about creating a P2P connection on remote (non-local) devices?

Collapse
 
carloslfu profile image
Carlos Galarza

Hi Jake, thanks! If you run the script in two remote computer with internet it works. I have updated the article for clarifying it. I am glad you liked the article :)

Collapse
 
hushino32 profile image
Hushino

Not work, any example of how peer_id: TCP_Connection works?

Collapse
 
viktor62yt profile image
Viktor 62

Hi Carlos! I have a problem. after I start the 2 consoles, both say that they connected, but I can't write any messages. Please help me!

Collapse
 
shivarajrs007 profile image
shivaraja

Hi Carlos I want build p2p connection .which package are suitable? Tell me.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay