Рубрики
Без рубрики

Как сделать P2P соединение за 10 минут на Node.js

– дать вам только попробовать, если хотите, я могу написать более глубокую статью, объясняющую, как все это работает. Итак, давайте начнем.

P2P.

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