【发布时间】:2018-05-15 20:45:36
【问题描述】:
我在 Azure Web 应用程序上托管了 ASP.NET Core 2.1 应用程序。我通过 WebSockets 发送照片 base64 字符串,然后通过 HttpClient 发送到 Azure Face API。
大约 150-250 个请求后,HttpClient 停止响应,我无法在应用程序的任何部分使用 HttpClient 类。
在我的本地主机中它可以正常工作,我从来没有遇到过这个问题。
public class FaceApiHttpClient
{
private HttpClient _client;
public FaceApiHttpClient(HttpClient client)
{
_client = client;
}
public async Task<string> GetStringAsync(byte[] byteData,string uri)
{
using (ByteArrayContent content = new ByteArrayContent(byteData))
{
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
HttpResponseMessage response = await _client.PostAsync(uri, content).ConfigureAwait(false);
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
}
}
DI:
services.AddHttpClient<FaceApiHttpClient>(
client => {
client.BaseAddress = new Uri("xxx");
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "xxx");
});
FaceApiClient 的方法在 Scoped Service 中调用:
public interface IFaceAPIService
{
Task<DataServiceResult<List<Face>>> GetFacesDataFromImage(byte[] byteArray);
}
public class FaceAPIService: ServiceBase, IFaceAPIService
{
private readonly IServerLogger _serverLogger;
private FaceApiHttpClient _httpClient;
//Consts
public const string _APIKey = "xxx";
public const string _BaseURL = "xxx";
public FaceAPIService(IServerLogger serverLogger, FaceApiHttpClient client)
{
_serverLogger = serverLogger;
_httpClient = client;
}
public async Task<DataServiceResult<List<Face>>> GetFacesDataFromImage(byte[] byteData)
{
try
{
// Request parameters. A third optional parameter is "details".
string requestParameters = "returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise";
// Assemble the URI for the REST API Call.
string uri = _BaseURL + "/detect" + "?" + requestParameters;
var result = await _httpClient.GetStringAsync(byteData, uri).ConfigureAwait(false);
List<Face> faces = JsonConvert.DeserializeObject<List<Face>>(result);
return Success(faces);
}
catch (Exception ex)
{
_serverLogger.LogExceptionFromService(ex);
return DataServiceResult.ErrorResult<List<Face>>(ex.Message);
}
}
}
a) 在 localhost 环境下它可以工作。我运行了 11 个模拟器,每秒有很多请求,但它从未中断(10 小时的模拟器,超过 2 万个请求)。
b) HttpClient 不仅在一个类中停止在应用程序的任何部分工作。
如何解决这个问题?
【问题讨论】:
-
HttpClient是如何注册到服务集合的?不建议创建过多的HttpClient实例。 -
由Services.AddHttpClient在Startup.cs类中添加
-
不知道是不是问题的根源,但是在使用共享客户端实例的时候不要重复添加DefaultRequestHeaders。事实上,除非所有请求都需要相同的标题,否则根本不应该这样添加标题。
-
死锁意味着并发问题,但我认为您的情况并非如此。这听起来更像是你的套接字用完了。你在哪里托管它?天蓝色?哪一层?它们通常对可以打开的套接字数量有限制,具体取决于 VM/计划层
-
你没有处理你的
HttpResponseMessage response。这可能是原因,但即使不值得这样做。
标签: c# asp.net-core