![](https://img.haomeiwen.com/i9522311/5e4a949e0f737cbd.png)
在抓取数据时,过程是非常缓慢的,需要使用进度条来不让用户发疯。
前堤
- 在抓取数据过程会非常缓慢,需要给页面加个进度条;
- 如果同一个时间只有抓取一个公司的数据,那太浪费Node高并发性了。
解决方案:
- 使用socket.io来进行长连接。
- 在遮掩层有叉关闭按键,用户可以抓取其他公司的数据。
本文内容
- 项目需要的库与技术
- 提交方案
- Socket长连接设计
- 运行项目
- 参考网站
- 展望
1.项目需要的库与技术
-
技术栈: Node.js, React, Socket.io
-
服务端所需的库: socket.io
-
客户端所需的库: socket.io-client
2.提交方案
- 进度条设计,在产品主页,会有一个数据记录总页数html元素(或js变量),这个总页数必须会有的,要不它也无法做数据分页。(进度条总数论情况而定-下载文件或上传文件另论);每一次抓取过程,服务端向客户端发送一个socket请求。
- 多个公司同时抓取,数据返回通过数据库联合控制,前端使用延时操作+socket来得到数据是否已经抓取完成并保存到数据库。
- 前端控制不同公司,不同的公司的长连接都在同一个页面完成,采用方法是一样,要分辨不同的操作。要设置一个state来控制。
3.Socket长连接设计
- 服务端
//index.js
import express from 'express';
const app = express();
export const server = require('http').createServer(app);
export const io = require('socket.io')(server);
//进度条 js
import { io } from '../index';
const adminNamespace = io.of(companyName); //打开compnayName命令空间
//barTotalTime为总量, currentBar为当时进度
adminNamespace.emit('news', JSON.stringify({ total: barTotalTime, current: currentBar }));
//抓取完时,关闭这个长连接
adminNamespace.on('connection', (socket) => {
setTimeout(() => socket.disconnect(true), 1000);
});
- 客户端
import io from 'socket.io-client';
//根据用户输入来创建命令空间
let socket = io(`http://localhost:8787/${companyName}`);
//获取到数据,进行操作
await this.state.socketIO.on('news', (data) => { ...})
//在客户端关闭长连接
this.state.socketIO.close();
4. 运行项目
-
下面将示例抓取z和zhenchen公司:
5.参考网站
- 上传进度条设计:https://heartsuit.github.io/2017/04/28/File-Upload-and-Download-with-Progress.html
- 了解简单的流程:https://medium.com/dailyjs/combining-react-with-socket-io-for-real-time-goodness-d26168429a34
- 什么都有:https://socket.io/
6.展望
- 在前端设计state控制socket,设计成字符串类型,没设计成array,这没法进行redux管理;前端能强制关闭socket长连接,不得利于安全。
- 后端与前端还细节处理方面还需要优化...
网友评论