## 📙 示例 3: 301-Networking 网络配置详解
### 🎯 学习目标
配置 libp2p 网络层,实现 P2P 连接和内容发现。
---
### 🌐 为什么需要网络?
```
┌─────────────┐ ┌─────────────┐
│ 本地节点 │ ◄─── P2P 网络 ───► │ 远程节点 │
│ Helia │ libp2p 协议 │ Helia/IPFS │
└─────────────┘ └─────────────┘
│ │
└──────────── CID ──────────────────┘
(内容寻址,无需服务器)
```
**本地存储**只能访问自己的数据,**网络配置**让你可以:
- 🔄 从远程节点检索内容
- 📤 向远程节点提供内容
- 🌍 参与分布式网络
---
### 🔧 libp2p 配置
libp2p 是 IPFS 的网络层,模块化设计:
```javascript
import { createLibp2p } from 'libp2p'
import { identifyService } from 'libp2p/identify'
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { webSockets } from '@libp2p/websockets'
import { bootstrap } from '@libp2p/bootstrap'
const libp2p = await createLibp2p({
// 1. 传输层
transports: [webSockets()],
// 2. 连接加密
connectionEncrypters: [noise()],
// 3. 流多路复用
streamMuxers: [yamux()],
// 4. 节点发现
peerDiscovery: [
bootstrap({
list: [
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa"
]
})
],
// 5. 服务
services: {
identify: identifyService()
}
})
```
---
### 🧩 核心组件解析
#### 1️⃣ 传输层 (Transports)
```javascript
// WebSocket 传输(浏览器和 Node.js 通用)
import { webSockets } from '@libp2p/websockets'
// TCP 传输(Node.js)
import { tcp } from '@libp2p/tcp'
// WebRTC 传输(浏览器 P2P)
import { webRTC } from '@libp2p/webrtc'
```
#### 2️⃣ 连接加密
```javascript
// Noise 协议 - 现代、高效的加密握手
import { noise } from '@chainsafe/libp2p-noise'
```
#### 3️⃣ 流多路复用
```javascript
// Yamux - 一个连接上多路复用多个流
import { yamux } from '@chainsafe/libp2p-yamux'
```
#### 4️⃣ 节点发现
```javascript
// Bootstrap - 连接到已知引导节点
import { bootstrap } from '@libp2p/bootstrap'
// mDNS - 本地网络发现
import { mdns } from '@libp2p/mdns'
// DHT - 分布式哈希表发现
import { kadDHT } from '@libp2p/kad-dht'
```
---
### 🚀 完整 Helia + libp2p 配置
```javascript
import { createHelia } from 'helia'
import { createLibp2p } from 'libp2p'
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { webSockets } from '@libp2p/websockets'
import { bootstrap } from '@libp2p/bootstrap'
// 创建 libp2p 节点
const libp2p = await createLibp2p({
transports: [webSockets()],
connectionEncrypters: [noise()],
streamMuxers: [yamux()],
peerDiscovery: [
bootstrap({
list: [
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt"
]
})
]
})
// 创建 Helia 节点(使用自定义 libp2p)
const helia = await createHelia({ libp2p })
console.log('Node started!')
console.log('Peer ID:', libp2p.peerId.toString())
```
---
### 🌍 通过网关访问内容
添加文件后,你可以在任何 IPFS 网关访问:
```javascript
// 添加文件
const cid = await fs.addBytes(data)
console.log('Added file:', cid.toString())
// Added file: bafkreife2klsil6kaxqhvmhgldpsvk5yutzm4i5bgjoq6fydefwtihnesa
```
访问链接:
```
https://ipfs.io/ipfs/bafkreife2klsil6kaxqhvmhgldpsvk5yutzm4i5bgjoq6fydefwtihnesa
```
---
### 📊 网络配置对比
| 环境 | 推荐传输 | 发现方式 |
|:---|:---|:---|
| 浏览器 | WebSocket + WebRTC | Bootstrap, DHT |
| Node.js | TCP + WebSocket | Bootstrap, mDNS, DHT |
| 混合 | WebSocket | Bootstrap |
---
### 🚀 运行命令
```bash
npm run 301-networking
```
---
### 📌 下一步
学习内容固定和垃圾回收 → **401-Providing**