關於Node.js的httpClieint請求報錯ECONNRESET的原因和解決措施

来源:http://www.cnblogs.com/lienhua34/archive/2016/11/12/6057662.html
-Advertisement-
Play Games

背景說明 最近在工作項目中有下麵一個場景: 使用Node.js的express框架實現了一個文件系統伺服器端,其中有個API用於客戶端上傳文件。客戶端使用Node.js的HttpClient來調用伺服器端的API上傳文件。 客戶端在上傳小文件時沒有任何問題,在上傳大文件時httpClient請求報錯 ...


背景說明

最近在工作項目中有下麵一個場景:

使用Node.js的express框架實現了一個文件系統伺服器端,其中有個API用於客戶端上傳文件。客戶端使用Node.js的HttpClient來調用伺服器端的API上傳文件。

客戶端在上傳小文件時沒有任何問題,在上傳大文件時httpClient請求報錯了下麵的錯誤,

{ [Error: socket hang up] code: 'ECONNRESET' } 

google了很多資料,最後看了一下Node.js的相關源碼終於知道了該問題的原因和解決辦法。

問題原因

出現該問題的原因是:Node.js提供的HttpServer預設設置了超時時間為2分鐘,當一個請求的處理時間超過2分鐘,HttpServer會自動將該請求的socket關閉掉,於是客戶端便收到了 ECONNRESET 的錯誤信息了。可以參考Node.js的源碼

下麵我們使用了一個例子來驗證一下。

伺服器端:

伺服器端使用express框架,註冊了一個路徑為““ 的 GET 方法路由處理函數。在該路由處理函數中,通過setTimeout方式設置了超時處理,3分鐘後超時才會對請求進行相應。

const express = require('express');
const util = require('util');
const app = express();

app.get("/", function(req, res, next) {
    util.log("Received a request.");

    setTimeout(function() {
        res.setHeader('transfer-encoding', 'chunked');
        res.status(200);
        util.log("timeout")
        res.write("hello world");
        res.end();
    }, 3 * 60 * 1000)
});
var server = app.listen(3001, function() {
    sutil.log("server listening at port 3001......");
});

客戶端:

客戶端通過調用http.request方法請求伺服器端的介面,並列印返回的信息。

const http = require('http');
const util = require('util')

var opt = {
    host: 'localhost',
    port: 3001,
    method: 'GET',
};
var req = http.request(opt, function(res) {
    util.log('STATUS:', res.statusCode);
    res.setEncoding('utf8');
    var resultText = '';
    res.on('data', (chunk) => {
        resultText += chunk;
    });
    res.on('end', () => {
        util.log(resultText);
    });
});

req.on('error', (e) => {
    util.log(e);
});

util.log("start request...")
req.end();

先啟動伺服器端,然後啟動客戶端。請求的結果如下所示:

伺服器端:

bbash-3.2$ node app.js                                                                                                                                                           
12 Nov 21:02:16 - server listening at port 3001......                                                                                                                              
12 Nov 21:02:22 - Received a request.                                                                                                                                               
12 Nov 21:05:22 - timeout

客戶端:

bash-3.2$ node app.js                                                                                                                                                               
12 Nov 21:02:22 - start request...                                                                                                                                                  
12 Nov 21:04:22 - { [Error: socket hang up] code: 'ECONNRESET' }

通過上面的運行結果可以看到,客戶端在請求等待了2分鐘之後,就報錯了 ECONNRESET 的錯誤。

解決措施

解決措施:調用伺服器端的server.setTimeout()方法將伺服器端的超時設置得大一點或者直接將超時機制關閉(將超時時間設置為0即可關閉)

就使用上面的代碼,客戶端不變,伺服器在文件最後調用server.setTimeout()方法,如下所示,

var server = app.listen(3001, function() {
    sutil.log("server listening at port 3001......");
});
server.setTimeout(0)

先啟動伺服器端,然後再啟動客戶端,運行結果如下:

伺服器端:

bash-3.2$ node app.js    
12 Nov 21:37:22 - server listening at port 3001......                                    
12 Nov 21:37:29 - Received a request.                                                    
12 Nov 21:40:29 - timeout

客戶端:

bash-3.2$ node app.js         
12 Nov 21:37:29 - start request...                                                       
12 Nov 21:40:29 - STATUS: 200                                                            
12 Nov 21:40:29 - hello world 

從上面運行結果可見,客戶端能夠正常接收到伺服器端的返回結果了。

(done)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ...
  • 1、簡介 EventBus是一個Android端優化的publish/subscribe消息匯流排,簡化了應用程式內各組件間、組件與後臺線程間的通信。比如請求網路,等網路返回時通過Handler或Broadcast通知UI,兩個Fragment之間需要通過Listener通信,這些需求都可以通過Eve ...
  • 1、簡介 ButterKnife是註解中相對簡單易懂的很不錯的開源框架 1.強大的View綁定和Click事件處理功能,簡化代碼,提升開發效率 2.方便的處理Adapter里的ViewHolder綁定問題 3.運行時不會影響APP效率,使用配置方便 4.代碼清晰,可讀性強 2、下載地址 https: ...
  • 有不足之處,請大家指出 一、 基礎知識 1、SDK的最新下載 搜索oracle,進入網站,à Downloads –> JavaSEI à 選第一個下載(其實java 8u111和8u112的區別就是在8u111的基礎上優化了一下,升了下級,實際使用沒什麼區別的) 其次註意一下選32位還是64位,是 ...
  • 無限級分類是一種設計技巧,在開發中經常使用,例如:網站目錄、部門結構、文章分類。筆者覺得它在對於設計表的層級結構上面發揮很大的作用,比如大家在一些平臺上面, 填寫邀請人,它就是一種上下級的關係,上級會有多個下級,下級又會有自己的分支,大多數都是利用遞歸的思想去實現。話不多說,首先來溫故一下遞歸的實現 ...
  • 如果你還沒有搭建gtest框架,可以參考我之前的博客:http://www.cnblogs.com/jycboy/p/6001153.html。。 1.The first sample: sample1 你把github上的項目導來之後,github地址:https://github.com/goo ...
  • RPC即遠程過程調用,它的實現方式有很多,比如webservice等。框架調多了,煩了,沒激情了,我們就該問自己,這些框架的作用到底是什麼,來找回當初的激情。 一般來說,我們寫的系統就是一個單機系統,一個web伺服器一個資料庫服務,但是當這單台伺服器的處理能力受硬體成本的限制,是不能無限的提升處理性 ...
  • 一、設置一個新的測試項目 在用google test寫測試項目之前,需要先編譯gtest到library庫並將測試與其鏈接。我們為一些流行的構建系統提供了構建文件: msvc/ for Visual Studio, xcode/ for Mac Xcode, make/ for GNU make,  ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...