node.js - NodeJS-Che cosa significa in realtà "socket hang up"?



(12)

Sto costruendo un web raschietto con Node e Cheerio, e per un certo sito web sto ricevendo il seguente errore (succede solo su questo sito, nessun altro che provo a racimolare.

Succede in una posizione diversa ogni volta, quindi a volte è url x che genera l'errore, altre volte url x va bene ed è un URL completamente diverso:

    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)

È molto difficile eseguire il debug, non so davvero da dove iniziare. Per iniziare, cos'è un errore di blocco del socket? È un errore 404 o simile? O significa solo che il server ha rifiutato una connessione?

Non riesco a trovare una spiegazione di questo ovunque!

EDIT: Ecco un esempio di codice che è (a volte) restituire errori:

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

Non c'è una chiamata diretta per chiudere la connessione, ma sto usando Node Request che (per quanto posso dire) usa http.get quindi non è necessario, correggimi se sbaglio!

EDIT 2: ecco un bit di codice effettivo, in uso, che causa errori. prodURL e altre variabili sono principalmente selettori jquery definiti in precedenza. Questo usa la libreria async per 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);
                }
            ]);
    });
}

https://ffff65535.com


Per gli utenti del modulo di request

Timeouts

Esistono due tipi principali di timeout: timeout di connessione e timeout di lettura . Un timeout di connessione si verifica se il timeout viene colpito mentre il client sta tentando di stabilire una connessione a una macchina remota (corrispondente alla chiamata connect() sul socket). Un timeout di lettura si verifica ogni volta che il server è troppo lento per inviare una parte della risposta.

Si noti che i timeout della connessione emettono un errore ETIMEDOUT e che i timeout di lettura emettono un errore ECONNRESET .


Anche la ragione può essere dovuta all'utilizzo dell'istanza di app di express anziché di const server = http.createServer(app) durante la creazione del socket del server.

Sbagliato

const express = require('express');
const http = require('http');
const WebSocket = require('ws');


const app = express();

app.use(function (req, res) {
  res.send({ msg: "hello" });
});

const wss = new WebSocket.Server({ server: app }); // will throw error while connecting from client socket

app.listen(8080, function listening() {
  console.log('Listening on %d', server.address().port);
});

Corretta

const express = require('express');
const http = require('http');
const WebSocket = require('ws');


const app = express();

app.use(function (req, res) {
  res.send({ msg: "hello" });
});

const server = http.createServer(app);
const wss = new WebSocket.Server({ server });

server.listen(8080, function listening() {
  console.log('Listening on %d', server.address().port);
});

Dai un'occhiata alla fonte :

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

Il messaggio viene emesso quando il server non invia mai una risposta.


Espandendo la risposta di Blender, questo accade in un certo numero di situazioni. I più comuni in cui mi imbatto sono:

  1. Il server si è bloccato.
  2. Il server ha rifiutato la connessione, molto probabilmente bloccato da User-Agent .

socketCloseListener , come delineato nella risposta di Blender, non è l'unico luogo in cui vengono creati errori di hangup.

Ad esempio, trovato here :

function socketOnEnd() {
  var socket = this;
  var req = this._httpMessage;
  var parser = this.parser;

  if (!req.res) {
    // If we don't have a response then we know that the socket
    // ended prematurely and we need to emit an error on the request.
    req.emit('error', createHangUpError());
    req._hadError = true;
  }
  if (parser) {
    parser.finish();
    freeParser(parser, req);
  }
  socket.destroy();
}

Puoi provare a curl con le intestazioni e in modo tale da essere inviato da Node e vedere se ottieni una risposta. Se non si ottiene una risposta con curl , ma si ottiene una risposta nel browser, è probabile che l'intestazione User-Agent venga bloccata.


Ho avuto lo stesso problema durante la richiesta ad alcuni server. Nel mio caso, l'impostazione di qualsiasi valore su User-Agent nelle intestazioni nelle opzioni di richiesta mi ha aiutato.

const httpRequestOptions = {
    hostname: 'site.address.com',
    headers: {
       'User-Agent': 'Chrome/59.0.3071.115'
    }
};

Non è un caso generale e dipende dalle impostazioni del server.


Ho usato require('http') per consumare il servizio https e ha mostrato " socked hang up ".

Quindi uso require('https') , invece, e funziona.


Nel mio caso, era perché una risposta application / json era formattata male (contiene una traccia dello stack). La risposta non è mai stata inviata al server. È stato molto difficile eseguire il debug perché non c'erano log. Questo thread mi aiuta molto a capire cosa succede.


Penso che vale la pena notare ...

Stavo creando test per le API di Google. Stavo intercettando la richiesta con un server improvvisato, quindi inoltrando quelli alla vera API. Stavo tentando di passare solo le intestazioni nella richiesta, ma alcune intestazioni stavano causando un problema con Express dall'altra parte.

Vale a dire, ho dovuto eliminare le intestazioni di connection , di accept e content-length prima di utilizzare il modulo di richiesta per inoltrarlo.

let headers = Object.assign({}, req.headers);
delete headers['connection']
delete headers['accept']
delete headers['content-length']
res.end() // We don't need the incoming connection anymore
request({
  method: 'post',
  body: req.body,
  headers: headers,
  json: true,
  url: `http://myapi/${req.url}`
}, (err, _res, body)=>{
  if(err) return done(err);
  // Test my api response here as if Google sent it.
})

Se stai riscontrando questo errore su una connessione https e sta accadendo istantaneamente, potrebbe essere un problema impostare la connessione SSL.

Per me era questo problema https://github.com/nodejs/node/issues/9845 ma per te potrebbe essere qualcos'altro. Se si tratta di un problema con ssl, dovresti essere in grado di riprodurlo con il pacchetto nodejs tls / ssl solo cercando di connetterti al dominio


Sono riuscito a risolvere questo problema ieri, eseguendo la mia applicazione web e il server node.js attraverso IntelliJ IDEA 2016.3.6. Tutto quello che dovevo fare era cancellare i miei cookie e la cache nel mio browser Chrome.


Un caso degno di nota: quando ci si connette da Node.js a Node.js usando Express, ottengo "socket hang up" se non prefisso il percorso URL richiesto con "/".


di seguito è riportato un semplice esempio in cui ho ricevuto lo stesso errore quando mi sono perso per aggiungere il codice commentato nell'esempio seguente. Scomporre il codice req.end () risolverà questo problema.

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




node.js