10分钟内建立P2P连接
准备
我们的第一个 P2P 连接
它是如何工作的?
这是一篇关于如何进行 P2P 聊天的简短指南。我的目的只是让你体验一下。如果你愿意,我可以写一篇更深入的文章来解释所有这些工作原理。好了,让我们开始吧。
准备
你唯一需要的就是最新的 NodeJS 和你最喜欢的编辑器(我的是 Visual Studio Code)。现在为我们的项目创建一个文件夹,打开命令行,使用 npm init 初始化一个 npm 仓库,并安装一些我们需要的库:
npm i --save discovery-swarm dat-swarm-defaults portfinder get-port
我们的第一个 P2P 连接
让我们从一个简单的 P2P 连接开始,感谢 Node.js 社区的一些优秀库,它太简单了:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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() | |
})() |
在两个控制台中运行此代码,就完成了!现在,您可以直接在局域网中的其他设备上运行它,即使没有互联网也可以工作,您还可以在世界各地任何其他有互联网的计算机或设备上共享和运行此脚本,它就可以正常工作,太棒了!
它是如何工作的?
此代码使用了Dat Project背后的技术。所有通信都是去中心化的,并通过 P2P 网络进行。
...
我欢迎大家提供反馈。欢迎提问,分享你使用 P2P 技术的经验,并分享你的想法!感谢阅读 :)
本系列的完成得益于 DatProject、Webtorrent 和 NodeJS 社区提供的出色工具。
如果您想了解有关技术和分布式 P2P 网络的更多信息,请在此处和 Twitter 上关注我:https://twitter.com/carloslfu
文章来源:https://dev.to/carloslfu/make-a-p2p-connection-in-10-minutes-4b32