自己做的网站容易被黑吗/信息流广告代理商排名
- 在【p2p、分布式,区块链笔记 Torrent】WebTorrent的上传和下载界面的示例中,主要通过
WebTorrent
类的add和seed函数实现相关功能。这两个函数都返回一个Torrent
类对象的实例。
seed函数
import createTorrent, { parseInput } from 'create-torrent' // "create-torrent": "^6.0.18"/*** Start seeding a new file/folder.* @param {string|File|FileList|Buffer|Array.<string|File|Buffer>} input* @param {Object=} opts* @param {function=} onseed called when torrent is seeding*/seed (input, opts, onseed) {if (this.destroyed) throw new Error('client is destroyed')if (typeof opts === 'function') [opts, onseed] = [{}, opts]this._debug('seed')opts = opts ? Object.assign({}, opts) : {}// no need to verify the hashes we createopts.skipVerify = trueconst isFilePath = typeof input === 'string'// When seeding from fs path, initialize store from that path to avoid a copyif (isFilePath) opts.path = path.dirname(input)if (!opts.createdBy) opts.createdBy = `WebTorrent/${VERSION_STR}`const onTorrent = torrent => {const tasks = [cb => {// when a filesystem path is specified or the store is preloaded, files are already in the FS storeif (isFilePath || opts.preloadedStore) return cb()torrent.load(streams, cb)}]if (this.dht) {tasks.push(cb => {torrent.once('dhtAnnounce', cb)})}parallel(tasks, err => {if (this.destroyed) returnif (err) return torrent._destroy(err)_onseed(torrent)})}const _onseed = torrent => {this._debug('on seed')if (typeof onseed === 'function') onseed(torrent)torrent.emit('seed')this.emit('seed', torrent)}const torrent = this.add(null, opts, onTorrent)let streamsif (isFileList(input)) input = Array.from(input)else if (!Array.isArray(input)) input = [input]parallel(input.map(item => async cb => {if (!opts.preloadedStore && isReadable(item)) {const chunks = []try {for await (const chunk of item) {chunks.push(chunk)}} catch (err) {return cb(err)}const buf = concat(chunks)buf.name = item.namecb(null, buf)} else {cb(null, item)}}), (err, input) => {if (this.destroyed) returnif (err) return torrent._destroy(err)parseInput(input, opts, (err, files) => {if (this.destroyed) returnif (err) return torrent._destroy(err)streams = files.map(file => file.getStream)createTorrent(input, opts, async (err, torrentBuf) => {if (this.destroyed) returnif (err) return torrent._destroy(err)const existingTorrent = await this.get(torrentBuf)if (existingTorrent) {console.warn('A torrent with the same id is already being seeded')torrent._destroy()if (typeof onseed === 'function') onseed(existingTorrent)} else {torrent._onTorrentId(torrentBuf)}})})})return torrent}
- 代码中的关键一句是:
const torrent = this.add(null, opts, onTorrent)
- 函数最终返回生成的 torrent 对象,其由add函数创建(第一个参数为null),代表正在进行 seeding 的种子。
- 这句代码实际上启动了种子(torrent)的创建和处理过程。它调用了
this.add()
方法,将opts
和onTorrent
回调传递进去,这些回调负责在种子完成处理时执行进一步的操作。 - 另一个关键的一句是
createTorrent(input, opts, async (err, torrentBuf) => {……})
-
调用
createTorrent
生成种子文件,并通过 onTorrent 处理后续操作(如 DHT 发布广播等) -
DHT 广播的过程发生在
onTorrent
回调中的这段代码部分:
if (this.dht) {// DHT 是否启用tasks.push(cb => { // 将一个任务推送到任务队列tasks 中torrent.once('dhtAnnounce', cb) // 监听torrent对象的dhtAnnounce事件。once意味着该事件处理器仅会触发一次,当dhtAnnounce事件发生时,执行回调 `cb`。})
}
- 当种子(
torrent
)开始上传并与其他节点建立连接时,WebTorrent 会尝试将种子信息通过 DHT 广播出去,允许其他客户端在没有 Tracker 的情况下发现这个种子。 torrent.once('dhtAnnounce', cb)
监听的是这个广播完成后的通知,当种子成功通过 DHT 被宣布时,cb
被执行,表示广播成功。
parallel(tasks, err => {if (this.destroyed) returnif (err) return torrent._destroy(err)_onseed(torrent)
})
parallel(tasks, cb)
用来并行执行所有任务,确保所有操作(如文件加载、DHT 广播等)都执行完毕后再继续。- 如果没有错误发生,
_onseed(torrent)
会被调用,表示种子已经开始上传,并且相关事件会被触发。
add函数
/*** Start downloading a new torrent. Aliased as `client.download`.* @param {string|Buffer|Object} torrentId* @param {Object} opts torrent-specific options* @param {function=} ontorrent called when the torrent is ready (has metadata)*/add (torrentId, opts = {}, ontorrent = () => {}) {if (this.destroyed) throw new Error('client is destroyed')if (typeof opts === 'function') [opts, ontorrent] = [{}, opts]const onInfoHash = () => {if (this.destroyed) returnfor (const t of this.torrents) {if (t.infoHash === torrent.infoHash && t !== torrent) {torrent._destroy(new Error(`Cannot add duplicate torrent ${torrent.infoHash}`))ontorrent(t)return}}}const onReady = () => {if (this.destroyed) returnontorrent(torrent)this.emit('torrent', torrent)}function onClose () {torrent.removeListener('_infoHash', onInfoHash)torrent.removeListener('ready', onReady)torrent.removeListener('close', onClose)}this._debug('add')opts = opts ? Object.assign({}, opts) : {}const torrent = new Torrent(torrentId, this, opts) // Create a new Torrent instance using the provided torrentId, current client (`this`), and options (`opts`).this.torrents.push(torrent) //Add the new torrent to the list of active torrents.torrent.once('_infoHash', onInfoHash) //监听 _infoHash 事件来检查是否存在重复的种子。torrent.once('ready', onReady) // 监听 ready 事件,当种子准备好时执行回调。torrent.once('close', onClose) // 监听 close 事件,清理资源和事件监听器。this.emit('add', torrent)return torrent}
- 关键一句是:
const torrent = new Torrent(torrentId, this, opts)
- 这行代码负责创建一个新的
Torrent
实例,并将其添加到当前 WebTorrent 客户端中,开始处理指定的种子。Torrent
类定义在lib\torrent.js
中。相关接口与功能可见docs\api.md
的Torrent部分 - 以下是对
torrent
方法的简单总结,使用表格呈现:
方法名 | 功能描述 | 参数 | 返回值 |
---|---|---|---|
torrent.destroy([opts], [callback]) | 删除种子,销毁与对等体的所有连接,并删除所有保存的文件元数据。 可以选择销毁存储的文件。 当完全销毁后调用 callback 。 | opts (可选): 配置销毁选项,例如是否销毁存储。callback (可选): 完成销毁后的回调。 | 无 |
torrent.addPeer(peer) | 向种子加入一个对等体。通常不需要手动调用,WebTorrent 会自动发现对等体。 手动添加时需确保 infoHash 事件已触发。 | peer : 对等体地址(如 “12.34.56.78:4444”)或 simple-peer 实例(WebRTC对等体)。 | true (添加成功)或 false (被阻止,可能因黑名单)。 |
torrent.addWebSeed(urlOrConn) | 向种子加入一个 Web Seed。 Web Seed 是通过 HTTP(S) 提供种子数据的源。 支持 URL 或自定义连接对象。 | urlOrConn : Web Seed URL 或自定义连接对象(实现 BitTorrent 协议的 Duplex 流,必须具有 connId )。 | 无 |
torrent.removePeer(peer) | 从种子中移除一个对等体。WebTorrent 会自动移除慢速或没有所需数据的对等体。 手动移除时指定对等体标识。 | peer : 对等体地址(如 “ip:port”)、peer id(hex 字符串)或 simple-peer 实例。 | 无 |
torrent.select(start, end, [priority], [notify]) | 选择一范围的数据块,优先下载该范围内的数据。 可以指定优先级和回调。 | start , end : 数据块范围(包含)。priority (可选): 优先级。notify (可选): 更新时触发的回调。 | 无 |
torrent.deselect(start, end) | 取消选择一范围的数据块,从而降低优先级。 | start , end : 数据块范围(包含)。 | 无 |
torrent.critical(start, end) | 将一范围的数据块标记为关键优先级,要求尽快下载。 | start , end : 数据块范围(包含)。 | 无 |
torrent.pause() | 暂停连接新的对等体。 此操作不影响现有连接或流。 | 无 | 无 |
torrent.resume() | 恢复与新对等体的连接。 | 无 | 恢复连接新的对等体,开始与更多对等体交换数据。 |
torrent.rescanFiles([callback]) | 扫描文件并验证存储中的每个数据块的哈希值,更新已下载的有效数据块的位图。通常用于外部进程添加文件时,确保 WebTorrent 识别这些文件。 完成后会调用回调。 | callback (可选): 扫描完成时的回调函数,callback(err) 。 | 无 |
torrent.on('infoHash', function () {}) | 当种子的 infoHash 确定时触发该事件。 | 无 | 无 |
torrent.on('metadata', function () {}) | 当种子的元数据(包括 .torrent 文件的内容)确定时触发该事件。 | 无 | 无 |
torrent.on('ready', function () {}) | 当种子准备好使用时触发该事件,表示元数据已就绪且存储准备好。 | 无 | 无 |
torrent.on('warning', function (err) {}) | 当种子遇到警告时触发该事件。此事件仅用于调试,不一定需要监听。 | err : 警告信息。 | 无 |
torrent.on('error', function (err) {}) | 当种子遇到致命错误时触发该事件,种子会被自动销毁并从客户端移除。 | err : 错误信息。 | 无 |
torrent.on('done', function () {}) | 当所有种子文件下载完成时触发该事件。 | 无 | 当所有文件下载完毕时触发,通常用于通知用户下载完成。 |
torrent.on('download', function (bytes) {}) | 当数据被下载时触发该事件,用于报告当前种子的下载进度。 | bytes : 本次下载的字节数。 | 用于监控下载进度,返回已下载的字节数,并可查询总下载量、下载速度等。 |
torrent.on('upload', function (bytes) {}) | 当数据被上传时触发该事件,用于报告当前种子的上传进度。 | bytes : 本次上传的字节数。 | 用于监控上传进度,返回已上传的字节数。 |
torrent.on('wire', function (wire) {}) | 每当一个新的对等体连接时触发该事件,wire 是一个 bittorrent-protocol 实现的 Duplex 流。可以使用它来扩展 BitTorrent 协议或进行其他自定义操作。 | wire : 与对等体连接的流对象。 | 用于处理与对等体的通信,可扩展 BitTorrent 协议或处理自定义协议。 |
torrent.on('noPeers', function (announceType) {}) | 每隔几秒当没有找到对等体时触发。announceType 指明了导致该事件触发的公告类型,可能是 'tracker' 、'dht' 、'lsd' 或 'ut_pex' 。如果尝试通过多个方式发现对等体,如跟踪器、DHT、LSD 或 PEX,将会为每种公告分别触发此事件。 | announceType : 字符串,指示公告类型,可以是 'tracker' 、'dht' 、'lsd' 、或 'ut_pex' 。 | 当没有对等体可用且公告方式不同(例如 tracker、DHT、LSD 或 PEX)时触发此事件。 |
torrent.on('verified', function (index) {}) | 每当一个数据块被验证时触发。事件的参数是被验证数据块的索引。 | index : 整数,表示被验证的块的索引。 | 每次数据块的哈希值被验证时触发此事件。 |
torrent & wire
-
torrent.on(‘wire’, function (wire) {}) 是在 WebTorrent 客户端中,当一个新的对等体(peer)连接时,触发的事件。当这个事件被触发时,wire 会作为参数传递给回调函数。wire 是一个 bittorrent-protocol 的实例,这是一个用于实现 BitTorrent 协议的 duplex 流(双向流),允许客户端与远程对等体(peer)进行数据交换。
-
以下是一个示例:
import MyExtension from './my-extension'torrent1.on('wire', (wire, addr) => {console.log('connected to peer with address ' + addr)wire.use(MyExtension)
})
- 实际上
torrent
中管理者相关的链接对象,如以下代码所示:
client.add(opts.magnetURI,torrent => {const wire = torrent.wires[0];wire.use(MyExtension());wire.MyExtension.on('hack_message', func);})client.seed(buf, torrent => {torrent.on('wire', (wire, addr) => {wire.use(MyExtension());wire.MyExtension.on('hack_message', func);}
})
wires
是一个数组,包含与该种子相关的所有 wire 对象。每个 wire 代表与一个对等体(peer)之间的连接。torrent.wires[0]
代表与第一个对等体(peer)建立的连接(wire)。
相关文章:

【p2p、分布式,区块链笔记 Torrent】WebTorrent的add和seed函数
在【p2p、分布式,区块链笔记 Torrent】WebTorrent的上传和下载界面的示例中,主要通过WebTorrent类的add和seed函数实现相关功能。这两个函数都返回一个Torrent类对象的实例。 seed函数 import createTorrent, { parseInput } from create-torrent // &…...

Redis穿透、击穿、雪崩
redis是一款常用的非关系型数据库,我们常用与作为数据缓存的组件。 接下来介绍一下面试中常被问到的三个概念以及简单的解决方法。 穿透 什么叫缓存穿透 缓冲穿透,是当有一个请求过来时,查询redis缓存不存在,又去查询数据库&…...

VBA高级应用30例应用3在Excel中的ListObject对象:插入行和列
《VBA高级应用30例》(版权10178985),是我推出的第十套教程,教程是专门针对高级学员在学习VBA过程中提高路途上的案例展开,这套教程案例与理论结合,紧贴“实战”,并做“战术总结”,以…...

2024系统架构师---上午综合题真题(重复考试知识难点)
1.感知层威胁 1)信息窃听:通过搭线或者电磁泄露造成数据隐私泄露;感知执行层主要由各种物理传感器组成,是整个物理信息系统中信息的来源。为了适应多变的环境,网络节点多布置在无人监管的环境中,因此容易被攻击者攻击,常见的针对感知执行层的攻击方式有; 2)感知破坏:…...

连接kafka消息队列报org.apache.kafka.clients.NetworkClient异常
启动kafka后,连接kafka消息队列报org.apache.kafka.clients.NetworkClient异常 could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient) 检查kafka运行日志,报The broker is trying to join the wrong clu…...

淘宝商品评论API:代码界的“买家秀”大揭秘
在淘宝这个神奇的购物天堂里,商品评论就像是隐藏的宝藏,等待着我们去挖掘。想象一下,如果你的代码能够自动获取这些评论,那岂不是像拥有了一台时光机,可以穿梭在买家的购物体验之中?今天,我们就…...

RabbitMQ队列详细属性(重要)
RabbitMQ队列详细属性 1、队列的属性介绍1.1、Type:队列类型1.2、Name:队列名称1.3、Durability:声明队列是否持久化1.4、Auto delete: 是否自动删除1.5、Exclusive:1.6、Arguments:队列的其他属性…...

游戏服务器和普通服务器的区别
服务器,顾名思义,是提供服务的设备,在计算机领域,服务器是指具有网络功能的高性能计算机,用于存储、处理和传输数据,而游戏服务器则是专门为游戏提供服务的服务器,它需要具备更高的性能、更稳定…...

Java 中的 Supplier:让数据生成更灵活
文章目录 1. Supplier 基础:无参返回,懒加载的利器2. 与 Optional 配合,优雅地处理默认值3. 惰性初始化缓存:提升性能4. 用于随机数、时间戳等动态数据的生成5. 结合 Stream 实现动态数据流6. 与工厂模式结合,动态创建…...

轻松理解操作系统 - Linux的数据块是如何储存数据的?
python入门 C入门 Linux 由于其开源、比较稳定等特点统治了服务端领域。 也因此,学习Linux 系统相关知识在后端开发等岗位中变得越来越重要,甚至可以说是必不可少的。 因为它的广泛应用,所以在程序员的日常工作和面试中,它都是经…...

青藤深度参编的终端安全国家标准正式发布
近日,国家市场监督管理总局、国家标准化管理委员会发布中华人民共和国国家标准公告,由TC260(全国网络安全标准化技术委员会)归口,公安部第三研究所牵头的GB/T 29240-2024《网络安全技术 终端计算机通用安全技术规范》&…...

软考:去中心化的部署有什么特点
微服务架构被认为是去中心化的,因为它具有以下特点 模块化:微服务架构将应用程序拆分为一系列小型服务,每个服务都是独立的模块,易于维护和扩展 。这种模块化设计使得每个服务可以独立于其他服务运行,没有单一的控制中…...

L8.【LeetCode笔记】回文数
1.题目 https://leetcode.cn/problems/palindrome-number/description/ 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数 是指正序(从左向右)和倒序(从右向左&…...

双版本android studio安装
安装双版本原因:不同的AS存在不兼容的情况,导致旧版本的项目在新项目下要各种修改,很讨厌,使用双版本,各使用各的就没有这样的问题了。 建议:先安装低版本安装版,再安装高版本免安装版…...

npm镜像的常用操作
查看当前配置的 npm 镜像 npm config get registry切换官方镜像 npm config set registry https://registry.npmjs.org/切换淘宝镜像(推荐) npm config set registry https://registry.npmmirror.com/切换腾讯云镜像 npm config set registry http://mirrors.cloud.tencent…...

Unity插件NodeCanvas之行为树的详细教程
文章目录 前言叶节点 Leafs1、行为 Action2、判断 Condition控制组件 Composites1、顺序执行器 Sequencer2、选择执行器 Selector3、概率选择执行器 Probability Selector4、权重选择执行器 Priority Selector5、平行执行器 Parallel6、轮流选择器 Flip Selector7、完整执行器 …...

Vue全栈开发旅游网项目(9)-用户登录/注册及主页页面开发
1.用户登录页面开发 1.查询vant组件 2.实现组件模板部分 3.模型层准备 4.数据上传 1.1 创建版权声明组件Copyright 新建文件:src\components\common\Copyright.vue <template><!-- 版权声明 --><div class"copyright">copyright xx…...

Flutter 的 Widget 概述与常用 Widgets 与鸿蒙 Next 的对比
一、Flutter 的 Widget 概述 Flutter 是 Google 开发的一款开源 UI 框架,旨在帮助开发者快速构建高性能、高保真度的移动、Web 和桌面应用程序。在 Flutter 中,UI 的构建完全是通过 Widget 来实现的。Widget 是 Flutter 中所有用户界面元素的基础构建块…...

微服务day04
网关 网关路由 快速入门 创建新模块:hm-gateway继承hmall父项目。 引入依赖:引入网关依赖和nacos负载均衡的依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"…...

Spring Boot 集成JWT实现Token验证详解
文章目录 Spring Boot 集成JWT实现Token验证详解一、引言二、JWT和Token基础1、什么是Token2、什么是JWT3、JWT的结构4、JWT的工作原理 三、集成JWT1、引入JWT依赖2、创建Token工具类3、创建拦截器4、注册拦截器 四、总结 Spring Boot 集成JWT实现Token验证详解 一、引言 在现…...

如何快速搭建一个spring boot项目
一、准备工作 1.1 安装JDK:确保计算机上已安装Java Development Kit (JDK) 8或更高版本、并配置了环境变量 1.2 安装Maven:下载并安装Maven构建工具,这是Spring Boot官方推荐的构建工具。 1.3 安装代码编辑器:这里推荐使用Inte…...

学习笔记:黑马程序员JavaWeb开发教程(2024.11.9)
9.1 Mybatis-基础操作-环境准备 这里也没做,到时候写案例,如果需要环境配置什么的,可以看看这个 9.2 Mybatis-基础操作-删除 删除需要动态获取需要删除的id,使用方法传参,#{}的方式实现 在编写的delete方法中&a…...

【软考】系统分析师第二版 新增章节 第20章微服务系统分析与设计
微服务系统是一类基于微服务架构风格的分布式系统,它将应用程序拆分成多个独立的小型服务,每个服务都运行在独立的进程中,并采用轻量级通信协议进行通信。这些服务可以由不同的团队开发、不同的编程语言编写,并且可以按需部署。微…...

抓包工具WireShark使用记录
目录 网卡选择: 抓包流程: 捕获过滤器 常用捕获过滤器: 抓包数据的显示 显示过滤器: 常用的显示过滤器: 实际工作中,在平台对接,设备对接等常常需要调试接口,PostMan虽然可以进…...

C++上机实验|多态性编程练习
1.实验目的 (1)理解多态性的概念。 (2)掌握如何用虚函数实现动态联编 (3)掌握如何利用虚基类。 2.实验内容 设计一个飞机类 plane,由它派生出歼击机类fighter和轰炸机类 bomber,歼击机类fighter 和轰炸机类bomber 又共同派生出歼轰机(多用途战斗机)。利用虚函数和虚基类描述…...

php伪协议介绍
PHP伪协议共有12种,具体如下: file:// — 访问本地文件系统http:// — 访问 HTTP(s) 网址ftp:// — 访问 FTP(s) URLsphp:// — 访问各个输入/输出流(I/O streams)php://stdin, php://stdout 和 php://stderrphp://inputphp://outputphp://memory 和 php://tempphp://filte…...

『事善能』MySQL基础 — 2.MySQL 5.7安装(一)
1、通过msi安装软件进行MySQL安装 (1)点击运行MySQL安装文件 (2)选择安装类型 我们选择自定义安装,点击Next。 说明 Develop Default:默认开发类型,安装MySQL服务器以及开发MySQL应用所需要的工…...

漫谈分布式唯一ID
文章目录 本系列前言UUIDDB自增主键Redis incr命令号段模式雪花算法 本系列 漫谈分布式唯一ID(本文)分布式唯一ID生成(二):leaf分布式唯一ID生成(三):uid-generator(待完…...

【复旦微FM33 MCU 开发指南】ADC
前言 本系列基于复旦微FM33LC0系列单片机的DataSheet编写,旨在提供手册解析和开发指南。 本文章及本系列其他文章将持续更新,本系列其它文章请跳转【复旦微FM33 MCU 外设开发指南】总集篇 本文章最后更新日期:2024/11/09 全文字数ÿ…...

ORB_SLAM3安装
ORB_SLAM3安装 一.前期准备1.1ubuntu查看当前版本的命令1.2 根据ubuntu版本,更新下载软件源1.3 先下载git1.4 vim语法高亮1.5 常见的linux命令 二.ORB-SLAM3下载2.1 ORB_SLAM3源码下载2.2 安装依赖库2.2.1 依赖库2.2.2 安装pangolin2.2.3 安装opencv2.2.4 Eigen3安装…...