Это краткое руководство о том, как сделать 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”