gpt4 book ai didi

c# - "Unable to read data from the transport connection: An existing connection was (NOT FORCIBLY) closed"在 RESTful Web 服务调用上

转载 作者:行者123 更新时间:2023-12-03 23:53:49 25 4
gpt4 key购买 nike

我已经阅读了许多讨论以下错误消息变体的堆栈溢出问题(例如 this one ):

System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.



但是,我在错误消息中收到以下变体:

System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was closed.



没有“被远程主机强行关闭”的提示。异常消息中没有关于它被关闭的确切原因的更多细节。

为什么会发生这种情况?这是否意味着我的一端出现了超时或其他问题,或者这是我们供应商方面的问题? (在我向我们的供应商提出调查请求之前,我想确定问题是谁的“错”)。

我正在下载的特定文件非常大,可能需要很长时间才能下载。

我的代码非常“标准” HttpClient “获取”逻辑:
    private async Task<string> GetReport(string fileNamePrefix, bool lookInCurrentFolder = false, bool returnEntireThing = true)
{
string fileName = $"{fileNamePrefix}-report-{DateTime.Now.ToString("yyyy-MM-dd")}.csv";

string downloadFolder = FileUtilities.GetPath(KnownFolder.Downloads);

string fileInDownloadFolder = Path.Combine(downloadFolder, fileName);

if ((lookInCurrentFolder && !File.Exists(fileName)) || (!lookInCurrentFolder && !File.Exists(fileInDownloadFolder)))
{
HttpClient client = HttpClientConstructor.GetHttpClient(acceptVersion: false, acceptType: "text/csv");
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));

using (HttpResponseMessage msg = await client.GetAsync("analytics/" + fileNamePrefix))
{
using (var fstr = new FileStream(lookInCurrentFolder ? fileName : fileInDownloadFolder, FileMode.Create))
{
using (GZipStream str = new GZipStream(await msg.Content.ReadAsStreamAsync(), CompressionMode.Decompress))
{
str.CopyTo(fstr);
}
}
}
}

return returnEntireThing ? File.ReadAllText(lookInCurrentFolder ? fileName : fileInDownloadFolder) : (lookInCurrentFolder ? fileName : fileInDownloadFolder);
}

稍微缩写, HttpClientConstructor是返回适当 HttpClient 的工厂Singleton(因为 Microsoft 建议在整个应用程序生命周期中使用一个 HttpClient)。可能会有多个 HttpClient 实例有几种不同的 acceptType配置。实例或多或少是这样创建的:
           var client = new HttpClient
{
BaseAddress = new Uri("..."),
Timeout = new TimeSpan(4, 0, 0)
};

client.DefaultRequestHeaders.Add("ApiToken", key);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(acceptType));

这里出了什么问题?为什么会出现奇怪的错误信息?这可能是我的问题吗?

编辑:在创建 HttpClient 之前,我正在设置这样的安全设置 HttpClientConstructor 中的实例:
ServicePointManager.DefaultConnectionLimit = 8;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

此外,这个问题是间歇性的 - 代码大部分时间都在工作,这是我第一次看到这种情况发生。

最佳答案

我在使用共享 HttpClient 连接到服务器进行 REST 调用时遇到了类似的问题。问题最终是客户端和服务器上的 KeepAlive 超时不匹配。客户端超时由 MaxServicePointIdleTime 设置ServicePointManager 上的设置,默认为 100 秒。服务器端空闲超时在我们的服务器中设置为较短的值。

与客户端相比,服务器上的超时时间较短会导致服务器在客户端尝试连接时偶尔关闭连接。这导致报告的异常。

请注意,我最终发现了问题,因为我在相同条件下也收到了此异常:

System.Net.WebException: The underlying connection was closed: A connection that was expected to be kept alive was closed by the server.

尽管可以通过为每个到服务器的连接使用一个新的 HttpClient 来解决该问题,但这与 Microsoft 的共享 HttpClient 的建议背道而驰。我建议将 MaxServerPointIdleTime 设置为较短的值,可能是 15 秒,以查看是否可以解决问题。或者,如果您有权访问服务器代码,您可以找到它的超时,并尝试将其设置为比客户端默认的 100 秒超时更长的值。

关于c# - "Unable to read data from the transport connection: An existing connection was (NOT FORCIBLY) closed"在 RESTful Web 服务调用上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52953756/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com