nodejs socket hang up


最近在开发Electron+Nodejs的App时,遇到了一个很奇葩的问题,https请求发送了之后无任何反应,如果这时候再重新发送https请求,就会出现socket hang up的问题.

socket-hang-up.png

访问网络的代码如下:

    
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请求库,安装和使用很简单.

Paste_Image.png

修改后的代码:


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);
        } 
    });
}

先测试一段时间再说吧.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容