NodeJS-“套接字挂起”实际上是什么意思?

我正在使用Node和Cheerio构建Web抓取工具,对于某个网站,我遇到以下错误(它仅在该网站上发生,没有其他我尝试抓取的错误。

每次都在不同的位置发生,因此有时url x是引发错误,有时url x是,并且完全是另一个URL:

    Error!: Error: socket hang up using [insert random URL, it's different every time]

Error: socket hang up
    at createHangUpError (http.js:1445:15)
    at Socket.socketOnEnd [as onend] (http.js:1541:23)
    at Socket.g (events.js:175:14)
    at Socket.EventEmitter.emit (events.js:117:20)
    at _stream_readable.js:910:16
    at process._tickCallback (node.js:415:13)

调试起来非常棘手,我真的不知道从哪里开始。首先,什么套接字挂起错误?是404错误还是类似错误?还是仅表示服务器拒绝连接?

我在任何地方都找不到这种解释!

编辑:这是(有时)返回错误的代码示例:

function scrapeNexts(url, oncomplete) {
    request(url, function(err, resp, body) {

        if (err) {
            console.log("Uh-oh, ScrapeNexts Error!: " + err + " using " + url);
            errors.nexts.push(url);
        }
        $ = cheerio.load(body);
        // do stuff with the '$' cheerio content here
    });
}

There is no direct call to close the connection, but I'm using Node Request which (as far as I can tell) uses http.get so this is not required, correct me if I'm wrong!

EDIT 2: Here's an actual, in-use bit of code that is causing errors. prodURL and other variables are mostly jquery selectors that are defined earlier. This uses the async library for Node.

function scrapeNexts(url, oncomplete) {
    request(url, function (err, resp, body) {

        if (err) {
            console.log("Uh-oh, ScrapeNexts Error!: " + err + " using " + url);
            errors.nexts.push(url);
        }
        async.series([
                function (callback) {
                    $ = cheerio.load(body);
                    callback();
                },
                function (callback) {
                    $(prodURL).each(function () {
                        var theHref = $(this).attr('href');
                        urls.push(baseURL + theHref);
                    });
                    var next = $(next_select).first().attr('href');
                    oncomplete(next);
                }
            ]);
    });
}
乐米亚2020/03/20 10:36:06

如果您通过https连接遇到此错误,并且该错误立即发生,则设置SSL连接可能会出现问题。

对我来说,这就是这个问题https://github.com/nodejs/node/issues/9845,但对您而言,可能是其他问题。如果ssl有问题,那么您应该能够使用nodejs tls / ssl软件包重现它,而仅尝试连接到域

ProItachi2020/03/20 10:36:06

我的情况不是错误,而是chrome浏览器的预期行为。Chrome使tls连接保持活动状态(为了提高速度),但是node.js服务器在2分钟后将其停止,您会收到错误消息。

如果您尝试使用边缘浏览器进行GET请求,则完全没有错误。如果您关闭Chrome窗口-您将立即收到错误消息。

那么该怎么办?1)您可以过滤此错误,因为它们不是真正的错误。2)也许有更好的解决方案:)

猿Tom2020/03/20 10:36:06

如果您使用的是node-http-proxy,请注意此问题,这将导致套接字挂起错误:https : //github.com/nodejitsu/node-http-proxy/issues/180

为了进行解析,同样在此链接中,只需在express.bodyParser()之前在声明路由中移动声明API路由(用于代理)。

猪猪Stafan小卤蛋2020/03/20 10:36:06

昨天通过IntelliJ IDEA 2016.3.6运行我的Web应用程序和node.js服务器,遇到了这个问题。我所要做的就是清除我的Cookie并在Chrome浏览器中缓存。

Sam飞云2020/03/20 10:36:06

这里似乎还有另外一种情况,那就是Electron不喜欢“ localhost”域名。就我而言,我需要更改此设置:

const backendApiHostUrl = "http://localhost:3000";

对此:

const backendApiHostUrl = "http://127.0.0.1:3000";

之后,问题就消失了。

这意味着DNS解析(本地或远程)也可能引起一些问题。

古一L2020/03/20 10:36:06

在我的情况下,这是因为application / json响应的格式错误(包含堆栈跟踪)。响应从未发送到服务器。调试起来非常棘手,因为没有日志。该线程对我很有帮助,以了解发生了什么。

飞云Eva宝儿2020/03/20 10:36:06

我同时进行网络(节点)和Android开发,并一起打开Android Studio设备模拟器和docker,它们都使用端口8601 socket hang up,在关闭Android Studio设备模拟器后,它报错,并且在节点端运行良好。不要同时使用Android Studio设备模拟器和docker。

西门小小2020/03/20 10:36:06

对于request模块用户

超时时间

超时主要有两种类型:连接超时读取超时一个连接超时如果在您的客户端试图建立到远程计算机(对应于一个连接超时被击中发生connect()在插座上的呼叫)。一个读超时发生时随时使用的服务器回送响应的一部分太慢。

请注意,连接超时发出ETIMEDOUT错误,而读取超时发出ECONNRESET错误。

GreenDavaidJim2020/03/20 10:36:06

另一个值得一提的情况(对于Linux和OS X)是,如果您使用类似的库https来执行请求,或者如果您将其https://...作为本地服务实例的URL进行传递,则将使用443作为保留专用端口的port,并且可能最终会出现错误Socket hang upECONNREFUSED出现错误。

而是使用port 3000,fe并执行http请求。

卡卡西西里2020/03/20 10:36:05

值得一提的情况是:使用Express从Node.js连接到Node.js时,如果未在请求的URL路径前加上“ /”作为前缀,则会出现“套接字挂断”的情况。

Pro阿飞Davaid2020/03/20 10:36:05

下面是一个简单的示例,当我在下面的示例中错过添加注释的代码时遇到了相同的错误。取消注释代码即可req.end()解决此问题。

var fs = require("fs");
var https = require("https");

var options = {
    host: "en.wikipedia.org",
    path: "/wiki/George_Washington",
    port: 443,
    method: "GET"
};

var req = https.request(options, function (res) {
    console.log(res.statusCode);
});


// req.end();