本文介绍了在Azure函数上大量使用Azure NotificationHubClient时会引发SocketException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用Azure功能通过Azure NotificationHubClient发送推送通知.该功能在实时环境的高峰时间被大量调用,结果,我们从NotificationHubClient.SendNotificationAsync()方法中抛出了许多SocketException.

We are using an Azure function to send push notifications via Azure NotificationHubClient. This function is called a lot at peak times on live environment and as a result we got a lot of SocketExceptions thrown from the NotificationHubClient.SendNotificationAsync() method.

异常详细信息:

Microsoft.Azure.NotificationHubs.Messaging.MessagingException: Unexpected exception encountered TimeStamp:2020-03-27T04:14:35.4655705Z ---> System.Net.Http.HttpRequestException: Cannot assign requested address ---> System.Net.Sockets.SocketException: Cannot assign requested address
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Microsoft.Azure.NotificationHubs.NotificationHubClient.SendRequestAsync(HttpRequestMessage request, String trackingId, HttpStatusCode[] successfulResponseStatuses, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at Microsoft.Azure.NotificationHubs.ExceptionsUtility.HandleUnexpectedException(Exception ex, String trackingId)
   at Microsoft.Azure.NotificationHubs.ExceptionsUtility.TranslateToMessagingException(Exception ex, Int32 timeoutInMilliseconds, String trackingId)
   at Microsoft.Azure.NotificationHubs.NotificationHubClient.SendRequestAsync(HttpRequestMessage request, String trackingId, HttpStatusCode[] successfulResponseStatuses, CancellationToken cancellationToken)
   at Microsoft.Azure.NotificationHubs.NotificationHubClient.SendNotificationImplAsync(Notification notification, String tagExpression, String deviceHandle, CancellationToken cancellationToken)

我们创建NotificationHubClient,如下所示:

We create the NotificationHubClient like:

new NotificationHubClient(connectionString, hubName, new NotificationHubClientSettings { OperationTimeout = TimeSpan.FromSeconds(10) });

new NotificationHubClient(connectionString, hubName, new NotificationHubClientSettings { OperationTimeout = TimeSpan.FromSeconds(10) });

我注意到,后面的Microsoft实现在每个新的NotificationHubClient实例上实例化一个新的HttpClient-可能是问题所在(众所周知的套接字耗尽),但是我不知道如何解决这个问题.

I've observed that the Microsoft implementation behind is instantiating a new HttpClient on each new NotificationHubClient instantiation - which would probably be the problem(the well known socket exhaustion), but I have no ideea how this could be tackled.

有人遇到过相同的问题并设法以某种方式解决了吗?谢谢

Has anyone confronted with the same problem and managed to fix it some way? Thanks

推荐答案

最后,我们设法通过注入来克服了问题

In the end we managed to overcome the problem by injecting

    IHttpMessageHandlerFactory _httpMessageHandlerFactory;

在我们的类中,并将其传递给构造函数中的notificationHubClient:

in our class and pass it to the notificationHubClient in the constructor:

    return new NotificationHubClient(connectionString, hubName, 
    new NotificationHubClientSettings
    {
       OperationTimeout = TimeSpan.FromSeconds(10),
       MessageHandler = _httpMessageHandlerFactory.CreateHandler()
    });

这篇关于在Azure函数上大量使用Azure NotificationHubClient时会引发SocketException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-18 13:31