在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ nodejs 如何設(shè)置http 請求的超時時間

nodejs 如何設(shè)置http 請求的超時時間

場景: 我需要在nodejs中調(diào)用一個處理時間較長的接口嗎,可能會超過120s。

  nodejs 默認(rèn)的 http 請求超時時間超過120s,則會返回超時。

問題:

如何修改默認(rèn)的超時時間呢?
最好是針對某個請求修改,不要影響到其他請求。

Koa示例:

// 這里虛擬一個處理時間較長的 接口
    const timeoutService = function (time) {
    time = time || 5000
    return new Promise((resolve, reject) => {
        try {
            setTimeout(function () {
                let data = [{
                                name: 'Tommy',
                                age: 10
                            }, {
                                name: 'Jupiter',
                                age: 18
                            }];
                resolve(data)
            }, time)
        } catch (e) {
            reject(e)
        }
    }).then(res => {
        return res
    }).catch(e => {
        return e
    })
}

router.get('/list', async (ctx) => {
    // 設(shè)置處理過程超過120s
    let data = await timeoutService(121000)
    ctx.status = 200;
    ctx.body = {
        success: true,
        data: data
    };
});

使用nodejs調(diào)用

// nodejs 調(diào)用
const GetList = (data) => {
  return new Promise((resolve, reject) => {
    let bs = JSON.stringify(data)
    console.log(bs)
    let encode = new Buffer(bs).toString('base64')
    let postData = JSON.stringify({ data: encode})
    var opt = {
        method: 'GET',
        host: 'localhost',
        port: 3100,
        path: '/list',
        headers: {
            'Content-Type': 'application/json',
            'Content-Length': Buffer.byteLength(postData),
            'Accept': 'application/json; charset=utf-8'
        }
    }
    let req = http.request(opt)
    req.on('response', (res) => {
        console.log('狀態(tài)碼:' + res.statusCode)
        console.log('響應(yīng)頭: ' + JSON.stringify(res.headers))
        let body = ''
        res.on('data', (data) => {
          body += data
        })
        res.on('end', () => {
          resolve(body)
        })
    })

    req.on('error', (e) => {
      console.log(e)
      console.error('請求遇到問題:' + e.message)
      reject(e.message)
    })
    req.setNoDelay(0)
    req.write(postData)
    req.end()
  })
}

function getTimeLast(label, startTime) {
    let finishTime = Date.now()
    let last = (finishTime - startTime) / 1000
    console.log(`${label} ${last}`)
}

let startTime = Date.now()
GetList({a: 1}).then(res => {
    console.log(res)
    getTimeLast('成功返回用時:', startTime)
}).catch(e => {
    console.log(e)
    getTimeLast('失敗返回用時:', startTime)
}) 

結(jié)果返回如下:

{"a":1}
{ Error: socket hang up
    at createHangUpError (_http_client.js:331:15)
    at Socket.socketOnEnd (_http_client.js:423:23)
    at emitNone (events.js:111:20)
    at Socket.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1055:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9) code: 'ECONNRESET' }
請求遇到問題:socket hang up
socket hang up
失敗返回用時: 120.018

回答
編輯回答
傻叼
2018年2月28日 03:05
編輯回答
初念

request.setTimeout

因為長時間沒有響應(yīng),客戶端認(rèn)為socket已經(jīng)斷開,而服務(wù)端并不認(rèn)為,讓你重用原來的socket。

2017年10月5日 04:13
編輯回答
溫衫

這個問題應(yīng)該是我沒有定位好問題所在。我自己梳理了一下。
timeout 可以理解成耐心值,客戶端發(fā)送請求時,可以設(shè)置自己的timeout。同時服務(wù)端也有自己的耐心值,二者互不干涉,二者都有權(quán)在超時后丟掉鏈接。

  • 客戶端發(fā)送請求時,如果在客戶端timeout 時間內(nèi),服務(wù)端仍沒有返回,那么它會終止這個請求。
  • 如果客戶端足夠耐心(timeout 夠大),但中間服務(wù)器沒有耐心,客戶端也會收到一個504 timeout
  • 如果目標(biāo)服務(wù)器在超時后仍未返回,那么鏈接也會關(guān)閉,客戶端不會收到返回。

所以確實是可以使用request.setTimeout來設(shè)置請求的timeout的,但是這個值不能超過服務(wù)器本身最大的限制。比如server.timeout = 5000;即使在setTimeout 中設(shè)置6000,仍是不生效的。所以如果瓶頸在與接口服務(wù)器的超時限制,修改客戶端的超時時間是無濟于事的。

2018年9月13日 23:52