给家里新买了一台TP-LINK WDR7400家庭网关,找了半天没有发现定时自动重连PPPOE的功能,于是想就用模拟登陆的方法来实现。使用Chrome的开发面板,抓取了页面的请求,分析了下其实关键只有3步,获取token,带着token请求断开连接,带着token请求连接。那用什么程序来在我的ubuntu 16.04上来做这个事情呢? 用shell很容易,但是转念一想不如用node,趁此机会复习下ES6,试一把同步写逻辑异步来执行。
于是写了下面的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
"use strict"; let co = require("co"); let request = require("co-request"); const BASE_URL = 'http://192.168.1.1' const LOGIN_OBJECT = JSON.parse('{"method":"do","login":{"password":"[REPLACE_TO_YOUR_PASSWORD]"}}'); const CONNECT_OBJECT = JSON.parse('{"network":{"change_wan_status":{"proto":"pppoe","operate":"connect"}},"method":"do"}'); const DISCONNECT_OBJECT = JSON.parse('{"network":{"change_wan_status":{"proto":"pppoe","operate":"disconnect"}},"method":"do"}'); function *requestRouter(uri, body) { let result = yield request({ uri: uri, method: 'POST', json: true, body: body }); return result.body; } co(function* () { // 先请求token let retData = yield requestRouter(BASE_URL, LOGIN_OBJECT); if(retData.error_code != 0) { console.error('failed to retrive token', retData); return; } // 获取到token let token = retData.stok; // 先断开pppoe retData = yield requestRouter(`${BASE_URL}/stok=${token}/ds`, DISCONNECT_OBJECT); if(retData.error_code != 0) { console.error('failed to disconnect', retData); return; } // 再连接pppoe retData = yield requestRouter(`${BASE_URL}/stok=${token}/ds`, CONNECT_OBJECT); if(retData.error_code != 0) { console.error('failed to connect', retData); return; } console.log('success'); }); |
这里面用到了ES6的几个特性,一个是生成器函数,一个是模板字符串,还有用co实现了逻辑同步书写。写完之后感觉还是比较流畅的,从callback hell中解脱出来的感觉非常好。
最后使用crontab配置好每天定时执行,就搞定了。
如果你需要下载执行,请把REPLACE_TO_YOUR_PASSWORD替换成你自己设备HTTP请求时发送的密码,应该是经过处理之后发送的,具体逻辑没仔细看,如果你有兴趣可以自己看下页面的js肯定能找到。node环境支持ES6即可,我用的7.4,npm装好co和co-request然后就可以执行了。