为啥用这个爬数据?py 不香吗?
回答:简单,js 方便在页面上验证,不用转换。
项目结构如下: 工程地址
├─ bin # 二进制执行脚本: npm start 会调这块
├─ node_modules # 利用npm管理的所有包及其依赖
├─ config # 配置文件:redis、mongodb、mysql 配置信息
├─ package.json # npm的配置文件:脚本、依赖等
├─ lib # 库:封装的一些工具
├─ proxy # 代理:管理连接 redis、mongodb、mysql
├─ public # 公共资源:一些样式
├─ views # 网页:127.0.0.1:8080 的样式等
├─ test # 测试:测试连接是否成功,目前只有测试 redis
├─ routes # 路由:目前有 3 个接口,/ 首页、/worker/:event post接口、/health 健康
└─ app.js # 工程入口:网络框架 express
服务端这块主要功能是:存储。
运行命令有:
npm test:用于测试连接,目前只有测试 Redisnpm start:用pm2启动npm stop: 用pm2停止
其实这块对应脚本就在 package.json里:
先跑起来
工程 clone下来:
工程基于 npm:mac下可使用 brew install npm进行安装。
首先依赖下载,直接运行:npm install。
预先准备 redis 、 mysql :
# redis
$ docker run -itd --name redis-test -p 6379:6379 redis
# mysql
$ docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
配置对应文件 config/local.json:
{
"redis": {
"host": "127.0.0.1",
"port": "6379"
},
"mysql": {
"connectionLimit": "15",
"host": "127.0.0.1",
"port": "3306",
"user": "user",
"password": "root",
"database": "123456"
}
}
- 测试
redis连接是否正常:npm test
忽略 Configuration property "redis.cluster" is not defined即可。
- 运行:
npm start
- 查看日志:
pm2 logs
- 打开
http://127.0.0.1:8080/****
综上工程算跑起来了。
源码解析
服务端这块东西较少,主要是存储。会对接 redis、mongodb、mysql。
- 首先了解入口
app.js: 网络框架使用的是express
- 规定一些请求的设置:
HTTP的body等。 - 规定路由规则:
routes/index
router.get('/', function (req, res) {
res.render('index', {title: 'schedule-server'});
});
router.post('/worker/:event', function (req, res) {
var event = req.params.event;
var collection = req.body;
worker.emit(event, req, res, collection);
});
router.get('/health', function (req, res) {
res.send({});
});
- 熟悉
worker.js
在上面路由中可看到:worker.emit(event, req, res, collection);触发一个事件
主要是根据 event调用不同的方法。
worker.js源码如下:
function Worker() {
// call方法使得 Worker 对象继承了 EventEmitter 对象上的方法
events.EventEmitter.call(this);
var prototypes = this.funs; // 所有方法
for (var i = 0; i < prototypes.length; i++) {
// on 绑定一个事件
this.on(prototypes[i], this[prototypes[i]]);
}
}
// 使用 inherits 方法, 功能与 call 有点重复
// inherited: 是基与原型的继承
// call: 是基于对象继承,可以获取对象方法
util.inherits(Worker, events.EventEmitter);
对应比如: EventEmitter
//event.js 文件
var events = require('events');
var emitter = new events.EventEmitter();
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener1', arg1, arg2);
});
emitter.on('someEvent', function(arg1, arg2) {
console.log('listener2', arg1, arg2);
});
emitter.emit('someEvent', 'arg1 参数', 'arg2 参数');
// 执行
$ node event.js
listener1 arg1 参数 arg2 参数
listener2 arg1 参数 arg2 参数
剩下就是定义了一堆方法: 举个栗子
Worker.prototype.find = function (req, res, collection) {
var name = collection.name;
var data = collection.data;
var sort = collection.sort;
if (sort == null) {
sort = {};
}
mongodb.find(name, data, sort, function (err, result) {
if (err) {
console.error('[%s]-[find] - 查询数据异常., error_message : [%s]', __dirname, JSON.stringify(err));
res.send({'result': '[find] - 查询数据异常.', 'is_success': false});
} else {
res.send({'result': result, 'is_success': true});
}
});
};
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情