Nodejs 发送HTTP消息时报错,非常诡异,求解!

Nodejs 发送HTTP消息时报错,非常诡异,求解!

正常往sina发送HTTP请求,但是会不时报如下错误, POST: api.weibo.com:443 /2/statuses/repost.json access_token=2.00rhElVDGI631Ee549f6f303v86EQB&id=3534310755900989&status=imax_check

Error: socket hang up at SecurePair.error (tls.js:948:15) at EncryptedStream.CryptoStream._done (tls.js:432:17) at EncryptedStream.CryptoStream._pull (tls.js:577:12) at SecurePair.cycle (tls.js:866:20) at EncryptedStream.CryptoStream.end (tls.js:405:13) at Socket.onend (stream.js:66:10) at Socket.EventEmitter.emit (events.js:123:20) at TCP.onread (net.js:417:51) 有人知道啥原因不?


10 回复

Nodejs 发送HTTP消息时报错,非常诡异,求解!

问题描述

在使用Node.js向新浪API(api.weibo.com:443)发送HTTP POST请求时,偶尔会遇到socket hang up的错误。错误信息如下:

Error: socket hang up
    at SecurePair.error (tls.js:948:15)
    at EncryptedStream.CryptoStream._done (tls.js:432:17)
    at EncryptedStream.CryptoStream._pull (tls.js:577:12)
    at SecurePair.cycle (tls.js:866:20)
    at EncryptedStream.CryptoStream.end (tls.js:405:13)
    at Socket.onend (stream.js:66:10)
    at Socket.EventEmitter.emit (events.js:123:20)
    at TCP.onread (net.js:417:51)

原因分析

socket hang up 错误通常表示TCP连接被另一端关闭了。这种情况可能由多种原因引起,例如网络不稳定、服务器响应超时、或者客户端与服务器之间的连接问题。

解决方案

1. 使用 request

request 是一个非常流行的HTTP客户端库,可以简化HTTP请求的发送,并且提供了一些处理连接问题的方法。

首先,你需要安装 request 库:

npm install request

然后,你可以使用以下代码来发送HTTP POST请求:

const request = require('request');

const options = {
    url: 'https://api.weibo.com/2/statuses/repost.json',
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    form: {
        access_token: '2.00rhElVDGI631Ee549f6f303v86EQB',
        id: '3534310755900989',
        status: 'imax_check'
    }
};

request(options, (error, response, body) => {
    if (error) {
        console.error('Error:', error);
    } else {
        console.log('Response:', body);
    }
});
2. 设置重试机制

为了应对偶尔的网络问题,可以在发送请求时添加重试机制。可以使用 retry 库来实现这一点:

npm install retry

然后,你可以这样修改代码:

const request = require('request');
const retry = require('retry');

const operation = retry.operation({
    retries: 3,
    factor: 3,
    minTimeout: 1 * 1000,
    maxTimeout: 60 * 1000,
    randomize: true
});

operation.attempt(() => {
    const options = {
        url: 'https://api.weibo.com/2/statuses/repost.json',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        form: {
            access_token: '2.00rhElVDGI631Ee549f6f303v86EQB',
            id: '3534310755900989',
            status: 'imax_check'
        }
    };

    request(options, (error, response, body) => {
        if (error) {
            if (operation.retry(error)) {
                return;
            }
            console.error('Error:', error);
        } else {
            console.log('Response:', body);
        }
    });
});

通过上述方法,你可以更好地处理网络不稳定导致的socket hang up错误,并提高请求的成功率。


不贴代码的话我想你只应该到新浪 API 的论坛问…

data = ‘access_token=2.00rhElVDGI631Ee549f6f303v86EQB&id=3534310755900989&status=imax_check’ var options = { hostname: ‘api.weibo.com’, port: 443, path: ‘/2/statuses/repost.json’, method: ‘POST’ };

var req = http.request(options, function(res) { console.log('STATUS: ’ + res.statusCode); }); });

req.on(‘error’, function(e) { console.log('problem with request: ’ + e.message); });

// write data to request body req.write(‘data\n’); req.end();

除了一层括号有错外(我手动去掉了)… 我运行是成功的, 这不是你出错的代码对吧

var http = require('http');

var options = { hostname: ‘api.weibo.com’, port: 443, path: ‘/2/statuses/repost.json’, method: ‘POST’ };

var req = http.request(options, function(res) { console.log('STATUS: ’ + res.statusCode); });

req.on(‘error’, function(e) { console.log('problem with request: ’ + e.message); });

// write data to request body req.write(‘data\n’); req.end();

出错的代码和这个一模一样,我这边只有一个环境会不时的抱着个错,我看过源码包,貌似是ssl什么地方出错了,手动运行怎么都不能重现,但是就会时不时的发生这种错。。。十分无奈。

或许是新浪服务器端的不作为吧。

我的运行结果: $ node test.js STATUS: 411

443不该是用https模块来进行访问吗?

我的关于443的回复怎莫不见了?

Jackson 对 443 的建议是对的。可是我改用 https 得到相同的结果。

$ node test.js 
STATUS: 411

411错误码是你post时http头content-length不对,你代码里没有发这个header,基本上4xx错误码都是客户端请求错误引起的

根据你的描述,错误信息 Error: socket hang up 通常表示网络连接问题或服务器响应超时。这种情况可能由于多种原因引起,例如网络不稳定、服务器临时不可用、请求超时等。

为了更好地调试这个问题,可以尝试以下步骤:

  1. 增加超时时间:有时候默认的超时时间过短可能会导致连接被提前关闭。
  2. 检查网络连接:确保客户端到目标服务器的网络连接是稳定的。
  3. 使用代理:如果目标服务器访问受限,可以尝试通过代理服务器进行访问。
  4. 重试机制:实现一个简单的重试机制,以便在网络不稳定时自动重试请求。

以下是一个使用 axios 库的示例代码,包含了设置超时时间和重试机制:

const axios = require('axios');
const delay = require('delay'); // npm install delay

async function sendRequest() {
    const url = 'https://api.weibo.com/2/statuses/repost.json';
    const options = {
        method: 'POST',
        url,
        data: {
            access_token: '2.00rhElVDGI631Ee549f6f303v86EQB',
            id: '3534310755900989',
            status: 'imax_check'
        },
        timeout: 10000, // 设置超时时间为10秒
        maxRedirects: 5 // 设置最大重定向次数
    };

    for (let attempt = 1; attempt <= 3; attempt++) { // 尝试三次
        try {
            const response = await axios(options);
            console.log('Response:', response.data);
            return response;
        } catch (error) {
            console.error(`Attempt ${attempt} failed:`, error.message);
            if (attempt < 3) {
                await delay(1000 * attempt); // 每次重试之间延迟一秒
            }
        }
    }

    throw new Error('Failed to send request after multiple attempts');
}

sendRequest().catch(error => {
    console.error('Final error:', error.message);
});

以上代码中:

  • 使用了 axios 库来发送 HTTP 请求。
  • 设置了超时时间为 10 秒。
  • 实现了一个简单的重试机制,最多尝试三次。
  • 如果三次都失败,则抛出错误。

请确保你已经安装了 axiosdelay 这两个库:

npm install axios delay

希望这能帮助你解决问题。如果问题仍然存在,建议检查目标服务器的状态或进一步调试网络连接。

回到顶部