7

我们使用 Azure 函数通过 Azure NotificationHubClient 发送推送通知。这个函数在实时环境的高峰时间被调用了很多,因此我们从 NotificationHubClient.SendNotificationAsync() 方法中抛出了很多 SocketExceptions。

异常详情:

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 如下:

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

我观察到背后的微软实现是在每个新的 NotificationHubClient 实例化上实例化一个新的 HttpClient - 这可能是问题(众所周知的套接字耗尽),但我不知道如何解决这个问题。

有没有人遇到过同样的问题并设法以某种方式解决它?谢谢

4

2 回答 2

3

最后我们设法通过注入解决了这个问题

    IHttpMessageHandlerFactory _httpMessageHandlerFactory;

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

    return new NotificationHubClient(connectionString, hubName, 
    new NotificationHubClientSettings
    {
       OperationTimeout = TimeSpan.FromSeconds(10),
       MessageHandler = _httpMessageHandlerFactory.CreateHandler()
    });
于 2020-04-16T06:34:02.873 回答
0

通知中心有一个 RESTful API。你可以在这里看到它。如果您想要更多控制,您可以围绕您需要的方法编写自己的包装器,确保将 HttpClient 实例设置为 Azure 函数中的静态成员变量。

于 2020-03-27T13:42:23.553 回答