美文网首页
nodejs socket hang up

nodejs socket hang up

作者: 路过麦田 | 来源:发表于2016-08-24 14:32 被阅读5399次

    最近在开发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);
            } 
        });
    }
    
    

    先测试一段时间再说吧.

    相关文章

      网友评论

          本文标题:nodejs socket hang up

          本文链接:https://www.haomeiwen.com/subject/qztosttx.html