Node中怎么利用WebSocket实现多文件下载功能 - web开发 -深圳网站优化推广公司
温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
获取短信验证码
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Node中怎么利用WebSocket实现多文件下载功能

发布时间:2021-07-21 11:10:47 来源:亿速云 阅读:539 作者:Leah 栏目:web开发

这篇文章将为大家详细讲解有关Node中怎么利用WebSocket实现多文件下载功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

列表

Node中怎么利用WebSocket实现多文件下载功能

下载列表

Node中怎么利用WebSocket实现多文件下载功能

本文地址仓库:https://github.com/Rynxiao/yh-tools,如果喜欢,欢迎star.

涉及技术

  • Express 后端服务

  • Webpack 模块化编译工具

  • Nginx 主要做文件gzip压缩(发现Express添加gzip有点问题,才弃坑nginx)

  • Ant-design 前端UI库

  • React + React Router

  • WebSocket 进度回传服务

其中还有点小插曲,最开始是使用docker起了一个nginx服务,但是发现内部转发一直有问题,同时获取宿主主机IP也出现了点问题,然后折磨了好久放弃了。(docker研究不深,敬请谅解^_^)

下载部分细节

Node中怎么利用WebSocket实现多文件下载功能

首先浏览器会连接WebSocket服务器,同时在WebSocket服务器上存在一个所有客户端的Map,浏览器端生成一个uuid作为浏览器客户端id,然后将这个链接作为值存进Map中。

客户端:

// list.jsx
await WebSocketClient.connect((event) => {
 const data = JSON.parse(event.data);
 if (data.event === 'close') {
  this.updateCloseStatusOfProgressBar(list, data);
 } else {
  this.generateProgressBarList(list, data);
 }
});
// src/utils/websocket.client.js
async connect(onmessage, onerror) {
 const socket = this.getSocket();
 return new Promise((resolve) => {
  // ...
 });
}
getSocket() {
 if (!this.socket) {
  this.socket = new WebSocket(
   `ws://localhost:${CONFIG.PORT}?from=client&id=${clientId}`,
   'echo-protocol',
  );
 }
 return this.socket;
}

服务端:

// public/javascript/websocket/websocket.server.js
connectToServer(httpServer) {
 initWsServer(httpServer);
 wsServer.on('request', (request) => {
  // uri: ws://localhost:8888?from=client&id=xxxx-xxxx-xxxx-xxxx
  logger.info('[ws server] request');
  const connection = request.accept('echo-protocol', request.origin);
  const queryStrings = querystring.parse(request.resource.replace(/(^\/|\?)/g, ''));
  
  // 每有连接连到websocket服务器,就将当前连接保存到map中
  setConnectionToMap(connection, queryStrings);
  connection.on('message', onMessage);
  connection.on('close', (reasonCode, description) => {
   logger.info(`[ws server] connection closed ${reasonCode} ${description}`);
  });
 });

 wsServer.on('close', (connection, reason, description) => {
  logger.info('[ws server] some connection disconnect.');
  logger.info(reason, description);
 });
}

然后在浏览器端点击下载的时候,会传递两个主要的字段resourceId(在代码中由parentId和childId组成)和客户端生成的bClientId。这两个id有什么用呢?

每次点击下载,都会在Web服务器中生成一个WebSocket的客户端,那么这个resouceId就是作为在服务器中生成的WebSocket服务器的key值。

bClientId主要是为了区分浏览器的客户端,因为考虑到同时可能会有多个浏览器接入,这样在WebSocket服务器中产生消息的时候,就可以用这个id来区分应该发送给哪个浏览器客户端

客户端:

// list.jsx
http.get(
 'download',
 {
  code,
  filename,
  parent_id: row.id,
  child_id: childId,
  download_url: url,
  client_id: clientId,
 },
);
// routes/api.js
router.get('/download', async (req, res) => {
 const { code, filename } = req.query;
 const url = req.query.download_url;
 const clientId = req.query.client_id;
 const parentId = req.query.parent_id;
 const childId = req.query.child_id;
 const connectionId = `${parentId}-${childId}`;
 const params = {
  code,
  url,
  filename,
  parent_id: parentId,
  child_id: childId,
  client_id: clientId,
 };
 const flag = await AnnieDownloader.download(connectionId, params);
 if (flag) {
  await res.json({ code: 200 });
 } else {
  await res.json({ code: 500, msg: 'download error' });
 }
});
// public/javascript/annie.js
async download(connectionId, params) {
  //...
 // 当annie下载时,会进行数据监听,这里会用到节流,防止进度回传太快,websocket服务器无法反应
 downloadProcess.stdout.on('data', throttle((chunk) => {
  try {
   if (!chunk) {
    isDownloading = false;
   }
   // 这里主要做的是解析数据,然后发送进度和速度等信息给websocket服务器
   getDownloadInfo(chunk, ws, params);
  } catch (e) {
   downloadSuccess = false;
   WsClient.close(params.client_id, connectionId, 'download error');
   this.stop(connectionId);
   logger.error(`[server annie download] error: ${e}`);
  }
 }, 500, 300));
}

服务端收到进度以及速度的消息后,回传给客户端,如果进度达到了100%,那么就删除掉存在server中的服务器中起的websocket的客户端,并且发送一个客户端被关闭的通知,通知浏览器已经下载完成。

// public/javascript/websocket/websocket.server.js
function onMessage(message) {
 const data = JSON.parse(message.utf8Data);
 const id = data.client_id;
 if (data.event === 'close') {
  logger.info('[ws server] close event');
  closeConnection(id, data);
 } else {
  getConnectionAndSendProgressToClient(data, id);
 }
}
function getConnectionAndSendProgressToClient(data, clientId) {
 const browserClient = clientsMap.get(clientId);
 // logger.info(`[ws server] send ${JSON.stringify(data)} to client ${clientId}`);
 if (browserClient) {
  const serverClientId = `${data.parent_id}-${data.child_id}`;
  const serverClient = clientsMap.get(serverClientId);
  // 发送从web服务器中传过来的进度、速度给浏览器
  browserClient.send(JSON.stringify(data));
  // 如果进度已经达到了100%
  if (data.progress >= 100) {
   logger.info(`[ws server] file has been download successfully, progress is ${data.progress}`);
   logger.info(`[ws server] server client ${serverClientId} ready to disconnect`);
   // 从clientsMap将当前的这个由web服务器创建的websocket客户端移除
   // 然后关闭当前连接
   // 同时发送下载完成的消息给浏览器
   clientsMap.delete(serverClientId);
   serverClient.send(JSON.stringify({ connectionId: serverClientId, event: 'complete' }));
   serverClient.close('download completed');
  }
 }
}

关于Node中怎么利用WebSocket实现多文件下载功能就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI

相关内容推荐

dr网站制作修改字体苏州公司网站制作费用石碣服装网站制作服务外包辽宁电子网站制作特点服务标准专业订制网站制作荔湾区律师网站制作哪家便宜梁山网站制作亳州网站制作公司哪家好平顶山网站外包门头制作如何制作一个镜像网站多语言外贸网站制作潍城区手机网站制作哪家服务好邯郸网站制作哪家强滑县网站制作推广哪家效果好台州门户网站制作外包公司网页制作与网站建设方案日程表哪个网站有手工制作制作网站的程序宁波专业网站制作服务商制作活动卡片的网站个人网站制作费用h5制作企业网站海南 网站制作网站logo制作教程重庆手机网站制作价格杏坛服装网站制作江苏专业网站制作服务标准淄博网站制作网络品牌网站制作公司竞标泉州在哪里制作网站自己制作动漫图像网站制作一个日本音乐网站湛江公司网站制作怎么做长沙行业网站制作服务哪家好视频分享网站制作济南效果好网站制作建设霍州微网站制作双语网站制作瀍河回族区网站外包门头制作php网站制作软件滨海新区网站制作哪家服务好影视网站解析接口制作教程武汉专业外贸网站制作维护网站制作效果好去哪找网站制作企业网站全景网站制作哪家有实力制作章的网站皇室战争制作卡牌网站动漫与游戏制作专业就业前景网站制作相册视频网站模板惠州市网站制作公司app制作网站源码如何自己在网上制作网页网站江北区网站制作服务个人如何制作一个手机网站石家庄网站制作费用咖啡菜单制作网站制作新网站多少钱照片打印制作网站图片上传网站制作网站制作怎么制作大连网站制作仟亿科技好重庆微信公众号小程序制作网站义乌找人制作服装网站要多少钱沧州商贸行业网站制作栖霞公司网站如何制作淘宝产品图制作的网站opencart网站制作天津制作制作网站免费咨询襄阳功能强大网站制作价格深圳福田制作网站线上网站制作软件英文美食制作网站文献信誉好的手机网站制作公司广东省网站制作企业东至网站制作哪家性价比高美食制作教学视频网站怎么制作博客网站樟木头网站建设制作哪家好在线购物网站制作网站设计制作的基本流程简答题类似问卷星制作试卷的网站网站制作FW尺寸厦门企业网站制作价格低温州外贸网站制作怎样制作网站版本延庆区智能网站制作厂家直供电商网站制作系统河源网站建设制作费用都江堰网站制作怎么收费鼓楼网站建设公司制作网站如何制作起点网站转转钓鱼网站制作知名的官方网站制作多少钱福州制作网站优质免费在线制作表情网站售后服务好的网站制作有哪些湖北品质网站制作服务标准自媒体制作素材网站自适应网站制作公司地址兰州城关区网站制作与开发泉山区企业网站制作哪家服务好天津电子网站制作流程服务标准凌迪科技的网站制作江苏什么是网站制作排名靠前忠县餐饮网站制作公司咨询电话厦门网站制作建设收费舟山园岭中文网站制作哪个好广告制作设计网站模板谷城网站制作公司昆明网站产品拍摄制作机构电话制作动画网站模板商丘专业网站设计制作费用用什么语言制作网站制作辣条的恶心过程网站广州网页制作网站维护合肥模板个人网站制作公司廊坊网站制作公司电商网站制作服务收费临沧制作一个企业网站多少钱安达网站制作公司新疆网站制作公司衢州网站制作哪个品牌好石排服装网站制作哪家快全国网站制作前十名佛山制作网站服务商昆明专业办理网站制作网站制作常用代码网站制作的页面比例坪地营销型网站制作哪家好如何制作网站下载链接青岛网站建设制作品牌企业聊城口碑好的网站开发制作酉阳手机网站制作公司联系电话营销网站建设制作开发沈阳网站制作全网性制作id钓鱼网站网站该如何制作如何制作一个网站源码无锡网站建设制作流程报价长沙企业网站制作外包公司厚街服装网站制作公司哪家好綦江网站制作公司哪家便宜定西市免费网页制作网站吴江网站制作网络推广方案直接制作小程序的网站制作网站需要什么密码零基础制作网站瑞安培训班网站制作多少钱舟山网站制作真的有用吗视频制作模板常用网站手机网站制作案例高新区中英文网站制作联系方式自己制作储存图片的网站清乐制作网站外包多少钱展板制作图片下载网站怎么制作电子公章网站java制作网站教程视频社区网站免费制作南京 网站模板如何制作网站制作标准规范gif图片制作网站成都网站制作价格多少制作地图的网站交易平台网站制作流程表单制作网站吕梁自适应网站制作制作网站怎么写广告语网站建设网站制作提供服务自己怎么制作一个网站盐田微网站制作多少钱浙江网站制作流程类型网站地图制作软件重庆企业网站制作维护怎么在手机上制作网站珠海本地外贸网站制作技术随便玩玩在线制作网站公众号微网站怎样制作东莞老牌网站制作生日祝福网站制作设计制作一个网站的费用湛江营销型网站制作怎么做支付网站制作商城类网站制作如何自己在网上制作网页网站宁夏银川网站定制开发制作瑞安中高端网站制作多少钱苏州网站制作哪家好小程序网站制作定制系统嘉善制作大型网站用什么软件下载网站程序制作教程淄博网站制作推广朝阳模板网站制作哪家好认真负责的网站制作价格行情南宁旅游网站设计制作矢量图制作网站制作自己单位的购物网站厦门网站制作服务费用武汉网站建设模板如何制作株洲商务网站设计制作师技术培训

合作伙伴

深圳网站优化推广公司

龙岗网络公司
深圳网站优化
龙岗网站建设
坪山网站建设
百度标王推广
天下网标王
SEO优化按天计费
SEO按天计费系统