如何让两个运行js-ipfs的浏览器IPFS节点互相连接?
浏览器端js-ipfs节点无服务器互联方案
浏览器环境下的js-ipfs节点默认不会暴露公网地址(没有端口映射、NAT穿透的话外部无法直接访问),所以node.id().addresses返回空数组是正常现象。下面是两种不依赖第三方服务器的节点互联方案:
方法1:同一局域网内用multicastDNS(mDNS)自动发现
mDNS是本地网络的多播协议,浏览器支持该API(你已经用HTTPS部署,满足环境要求),默认js-ipfs没开启,需要手动配置:
- 初始化节点时启用mDNS服务:
import { create } from 'ipfs-core' const node = await create({ libp2p: { services: { mdns: { enabled: true, // 开启mDNS interval: 1000 // 可选:调整广播间隔,单位毫秒 } } } })
- 监听mDNS发现事件并自动连接:
node.libp2p.services.mdns.addEventListener('peer', async (event) => { const peerInfo = event.detail console.log('发现局域网节点:', peerInfo.id.toString()) try { await node.swarm.connect(peerInfo.multiaddrs[0]) console.log('成功连接到节点:', peerInfo.id.toString()) } catch (err) { console.error('连接失败:', err) } })
开启后,同一局域网内的节点会自动发现彼此并尝试连接,无需手动干预。
方法2:手动交换节点信息(跨局域网/无mDNS场景)
如果两台设备不在同一局域网,或者mDNS无法工作,可以手动获取节点的临时WebRTC地址并交换:
- 获取自己的节点ID:
const peerId = (await node.id()).id.toString() console.log('我的节点ID:', peerId)
- 触发节点生成临时WebRTC地址:
浏览器节点只有在发起/接收连接时才会生成临时WebRTC地址,你可以先尝试连接一个公共引导节点,再查看本地地址:
// 先连接一个公共节点触发地址生成 await node.swarm.connect('/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN') // 获取本地临时地址 const addrs = await node.libp2p.getMultiaddrs() console.log('我的临时WebRTC地址:', addrs.map(a => a.toString()))
- 手动将节点ID和地址传给另一台设备,然后发起连接:
// 替换成对方的节点ID和地址 await node.swarm.connect('/p2p/<对方节点ID>/webrtc/<对方WebRTC地址>')
注意:WebRTC地址是临时的,节点重启后会失效,需要重新交换。
验证连接效果
连接成功后,你可以通过以下命令测试功能:
// 查看已连接的对等节点 const peers = await node.swarm.peers() console.log('已连接节点:', peers.map(p => p.peer.toString())) // 测试文件传输:节点A添加文件 const { cid } = await node.add(new TextEncoder().encode('Hello from Node A')) // 节点B获取文件 const data = await node.cat(cid) console.log('收到内容:', new TextDecoder().decode(data)) // 测试PubSub:节点B订阅主题 await node.pubsub.subscribe('test-topic', (msg) => { console.log('收到PubSub消息:', new TextDecoder().decode(msg.data)) }) // 节点A发布消息 await node.pubsub.publish('test-topic', new TextEncoder().encode('Hello from Node A')) // 查看对方的wantlist const wantlist = await node.bitswap.wantlistForPeer('<对方节点ID>') console.log('对方的wantlist:', wantlist)
内容的提问来源于stack exchange,提问作者Michael G
相关产品推荐
相关产品推荐

