当前位置: 首页 > 知识库问答 >
问题:

NodeJS-“插座挂断”到底是什么意思?

阳兴文
2023-03-14

我正在用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
    });
}

没有直接调用来关闭连接,但我使用的是节点请求(据我所知),它使用的是http.get,所以这不是必需的,如果我错了,请更正我!

编辑2:这里有一个实际的、正在使用的代码,它导致了错误。produrl和其他变量大多是前面定义的jquery选择器。这将为节点使用async库。

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

共有2个答案

莘俊能
2023-03-14

看一看出处:

function socketCloseListener() {
  var socket = this;
  var parser = socket.parser;
  var req = socket._httpMessage;
  debug('HTTP socket close');
  req.emit('close');
  if (req.res && req.res.readable) {
    // Socket closed before we emitted 'end' below.
    req.res.emit('aborted');
    var res = req.res;
    res.on('end', function() {
      res.emit('close');
    });
    res.push(null);
  } else if (!req.res && !req._hadError) {
    // This socket error fired before we started to
    // receive a response. The error needs to
    // fire on the request.
    req.emit('error', createHangUpError());
    req._hadError = true;
  }
}

该消息是在服务器从未发送响应时发出的。

胡和煦
2023-03-14

抛出套接字挂起时有两种情况:

当您作为客户端向远程服务器发送请求但没有收到及时响应时。套接字已结束,引发此错误。您应该捕获这个错误,并决定如何处理它:是否重试请求,将其排队等待以后等。

当您作为服务器(可能是代理服务器)接收到来自客户端的请求,然后开始执行该请求(或将该请求中继到上游服务器),并且在您准备好响应之前,客户端决定取消/中止该请求。

此堆栈跟踪显示客户端取消请求时发生的情况。

Trace: { [Error: socket hang up] code: 'ECONNRESET' }
    at ClientRequest.proxyError (your_server_code_error_handler.js:137:15)
    at ClientRequest.emit (events.js:117:20)
    at Socket.socketCloseListener (http.js:1526:9)
    at Socket.emit (events.js:95:17)
    at TCP.close (net.js:465:12)

http.js:1526:9行指向@blender提到的相同的socketcloselistener,特别是:

// This socket error fired before we started to
// receive a response. The error needs to
// fire on the request.
req.emit('error', createHangUpError());

...

function createHangUpError() {
  var error = new Error('socket hang up');
  error.code = 'ECONNRESET';
  return error;
}

如果客户端是浏览器中的用户,这是一个典型的情况。加载某些资源/页面的请求需要很长时间,用户只需刷新页面即可。这样的操作会导致先前的请求被中止,在服务器端引发此错误。

由于这个错误是由一个客户端的愿望引起的,所以他们不期望收到任何错误消息。因此,不需要将此错误视为严重错误。别理它。在这样的错误中,客户机监听的res套接字虽然仍可写,但会被破坏,这是一个事实。

console.log(res.socket.destroyed); //true

因此,除了显式关闭响应对象外,没有发送任何内容的意义:

res.end();

但是,如果您是一个代理服务器,它已经将请求中继到上游端,那么您应该做的就是中止您对上游端的内部请求,表明您对响应不感兴趣,这反过来会告诉上游服务器,也许是停止一个昂贵的操作。

 类似资料:
  • 问题内容: 我有以下示例: 在这段代码中,我可以理解Enum创建了一个Enum类型的Sizes。 我的问题是:EnumSet类型的对象吗?到底是什么意思 我真的很想更好地理解它。 问题答案: 对于任何变量,可以在其声明中找到其类型: 是的,(应该命名,因为它是一个集合)是type 。它也应该被泛化,因此被声明为 它的意思是那是type 。一个是一个包含一个特定的枚举类型的枚举例如,在比其他更有效的

  • 问题内容: 这是代码: 但是当我将“ #round”更改为“ this”时。它不会工作。为什么?(实际上是可行的,但是当我将它们放入setInterval()时,它将无法工作) 更改为“ this”,将无法使用。 问题答案: 是对调用当前函数的成员的引用… 那么您可以将其包装在jquery函数中以选择它,就像选择其他选择器一样。 因此调用匿名函数,这样它就不会被可引用成员调用,因此它默认为该对象。

  • 问题内容: 在github上研究node.js源代码时,我已经看过很多次了。 谁能解释这个功能的作用? 问题答案: 该函数返回内部模块,如require。它不是公共的,因此您不应在代码中依赖它,但如果您想了解事物的工作原理,则可以将其用于节点的低级对象。 例如,在这里 注册绑定。它导出 构造函数。在它的进口

  • 问题内容: 我想使用作为我的单元测试的基本目录(创建很多文件)。此属性指向当前工作目录是否正确(例如,由“ cd”命令设置)? 问题答案: 这java是运行JVM的目录。不必位于用户的主目录中。它可以在用户有权运行Java的任何地方。 因此,如果你cd进入,然后运行你的程序,将是。 另一个属性指向用户目录。如或或。

  • 问题内容: 我对Java非常陌生,只想确认是什么?它类似于Float还是Int?任何帮助,将不胜感激。我有时还会看到大写字母,有时看到的是小写字母。如果有人可以弄清楚这意味着什么,那就太好了! 问题答案: Double是包装器类, Double类将原始类型double的值包装在对象中。类型为Double的对象包含单个类型为double的字段。 此外,此类提供了几种将double转换为String和