Это краткое руководство о том, как сделать P2P-чат. Моя цель – дать вам только попробовать, если хотите, я могу написать более глубокую статью, объясняющую, как все это работает. Итак, давайте начнем.
Подготовка
Единственное, что вам понадобится, это последняя версия NodeJS и ваш любимый редактор, мой – Visual Studio Code. Теперь создайте папку для нашего проекта, откройте командную строку, инициализируйте npm-репо с помощью npm init и установите некоторые библиотеки, которые нам понадобятся:
npm i --save discovery-swarm dat-swarm-defaults portfinder get-port
Я объясню, что делает эта библиотека позже.
Наше первое P2P-соединение
Давайте начнем с простого P2P-соединения, благодаря некоторым замечательным библиотекам из сообщества Node.js это слишком просто:
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()
})()Запустите этот код на двух консолях и все! Теперь вы можете запустить его на другом устройстве прямо в вашей локальной сети и он должен работать даже без интернета, также вы можете поделиться и запустить этот скрипт на любом другом компьютере с интернетом, он просто работает, так приятно!
Что дальше?
Мы создадим P2P-чат для нашего долгосрочного проекта, используя этот код. Чат будет иметь сквозное шифрование и сможет проверять сообщения.
Оригинал: “https://www.codementor.io/@carlosgalarza/make-a-p2p-connection-in-10-minutes-kb6k5505s”