Skip to content

Instantly share code, notes, and snippets.

@carloslfu
Last active April 16, 2023 20:01
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save carloslfu/ec389a3d55e07edbf48e23fbd8d65689 to your computer and use it in GitHub Desktop.
Save carloslfu/ec389a3d55e07edbf48e23fbd8d65689 to your computer and use it in GitHub Desktop.
Make a P2P connection in 10 minutes
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()
})()
@enkiplusplus
Copy link

What is the licence of this code? I would like to use/extend it.

@enkiplusplus
Copy link

enkiplusplus commented Oct 21, 2018

I already imported the code here:
https://github.com/enkiplusplus/p2pengine

@caasi-corp
Copy link

Hi, I would like to know how can you create your own private node, I noticed that it connects to a peer node 9071e511e039abc671ac93cdec53e02bb9953994d52ec821bf3e14670d15fa81

@Berkmann18
Copy link

Berkmann18 commented Nov 13, 2018

Is l.22 meant to be

Function to safely call console.log with readline interface active

Instead of

Function for safely call console.log with readline interface active

?

@alexvirtech
Copy link

Hi, Carlos,
It's a very interesting example.
You wrote in the article https://medium.com/@carloslfu/make-a-p2p-connection-in-10-minutes-57d9559fd1c that it works in any other computer with internet. I tried, but it's not working if the computers are not in the same LAN. Can you explain how it's possible?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment