最近在开发Electron+Nodejs的App时,遇到了一个很奇葩的问题,https请求发送了之后无任何反应,如果这时候再重新发送https请求,就会出现socket hang up
的问题.
访问网络的代码如下:
function execute_http_request(options, body, callback) {
var req = https.request(options, function (res) {
var body = '';
res.setEncoding('utf-8');
res.on('data', function (chunk) {
body += chunk;
});
res.on('end', function () {
callback(null, body);
});
});
// 不管有没有设置超时,均会出现socket hang up的情况
// req.setTimeout(1500, function () {
// console.log('timed out');
// req.abort();
// });
req.on('error', function (e) {
callback(e);
});
req.write(body)
req.end();
}
但是代码运行在Node.js下是没有问题的,一旦运行起Electron搭建的GUI问题就会很频繁的出现,Window环境没有测试,macOS经测试出现的概率差不多为1/10, Linux出现这个问题的概率为100%,在stackoverflow
上也没有找到解决的办法,猜测应该是Electron库的问题,可能跟Nodejs的https库有些不兼容吧,后来更换了request库,还是一样的结果,动不动就没反映,或者hang up.
后来在Google上搜索了一些Nodejs平台的http库,发现了Unirest,这是一轻量级的http请求库,安装和使用很简单.
修改后的代码:
let unirest = require('unirest');
function execute_http_request(options, body, callback) {
let url = 'https://' + options.hostname + options.path;
console.log('post: ' + url);
// console.log('headers: ' + JSON.stringify(options.headers));
unirest.post(url).strictSSL(false).headers(options.headers)
.send(body).end((response) => {
console.log('code: ' + response.code + ', body: ' + response.body);
callback(null, response.body);
});
}
简单替换掉之前的代码之后,发现第二次访问是可以正常返回结果的,但是后面的某一次还是有很大的几率会出现无返回值的情况.
后来查看官方的API手册发现了这个方法timeout()
,在代码中添加了超时设置以后,竟然正常了,但是会有那么一点点慢,估计是设置的超时时间不合适的缘故吧.
......
unirest.post(url).strictSSL(false).headers(options.headers).timeout(1500)
......
在投入Nodejs开发之后,发现Nodejs上的坑绝不比Android上的少,有些是前人踩过的,有些是没有踩过的,不管有没有踩过,遇到后总要把它填上,本来想把自己这两个月开发过程中遇到的问题总结一下,但是一旦忙起来真是是根本停不下来,算了,还是看心情吧...
用了一段时间以后,发现虽然没有了socket hang up
的问题,但是服务器返回的response
偶尔会出现undefined
的情况,后来看到unirest库也是对request库上层进行的封装,所以理论上完全可以替换为request,经过几分钟的替换,发现效果确实还好,测试的几十次中没有再出现undefined
的情况了,代码如下:
let request = require('request');
function execute_http_request(options, body, callback) {
let o = {
url: 'https://' + options.hostname + options.path,
method: 'POST',
strictSSL: false,
timeout: 1500,
headers: options.headers,
body: body
};
// console.log(o);
request(o, (err, response, body) => {
if (err) {
callback(err);
} else {
// console.log('response = ' + JSON.stringify(response, null, 4));
console.log('body = ' + body);
callback(null, body);
}
});
}
先测试一段时间再说吧.
网友评论