【问题标题】:SignalR long polling repeatedly calls /negotiate and /hub POST and returns 404 occasionally on Azure Web AppSignalR 长轮询重复调用 /negotiate 和 /hub POST 并偶尔在 Azure Web App 上返回 404
【发布时间】:2021-12-20 04:16:42
【问题描述】:

我们已在 Azure Web 应用(Windows 应用服务计划)上运行的 ASP.NET Core 5.0 Web 项目上启用 SignalR。我们的 SignalR 客户端是使用 @microsoft/signalr NPM 包(版本 5.0.11)的 Angular 客户端。

我们有一个位于/api/hub/notification 的中心。

对于我们的大多数客户端来说,一切都按预期工作,网络套接字连接已建立,我们可以从客户端调用方法到服务器,反之亦然。

对于我们的一些客户,我们在短时间内看到大量对POST /api/hub/notification/negotiatePOST /api/hub/notification 的请求(每个客户端每分钟有多个请求)。由于我们看到了POST /api/hub/notification 请求,这些客户端似乎切换到长轮询而不是使用网络套接字。

我们怀疑受影响的客户端可能位于禁止 Web 套接字的代理或防火墙后面,因此连接首先切换到长轮询。

以下屏幕截图显示了单个用户在短时间内对中心端点的请求。该列表很长,因为只要用户打开我们的网站,这种模式就会重复。我们看到了两件奇怪的事情:

  1. 客户端每 15 秒重复调用两次/negotiate
  2. POST /notification?id=<connectionId> 的调用只用了15 秒,随后具有相同连接ID 的调用返回404 响应。然后该模式重复并再次调用/negotiate

出于测试目的,我们仅在客户端中启用了长轮询。这也按预期对我们有用。不幸的是,我们目前无法访问发生此行为的用户的浏览器或网络,因此我们很难重现该问题。

还有一些注意事项:

  1. 我们目前只有一个 Web 应用实例正在运行。
  2. 我们将 Redis 背板用于未来的横向扩展方案。
  3. ARR 关联 cookie 已启用,Azure Web 应用程序中的 Web 套接字也已启用。
  4. Web 应用实例不会受到高 CPU 使用率或高内存使用率的影响。
  5. 除了添加 Redis 背板外,我们没有更改任何 SignalR 选项。我们只使用services.AddSignalR().AddStackExchangeRedis(...)endpoints.MapHub<NotificationHub>("/api/hub/notification")
  6. 网站在 HTTPS 上运行。
  • 什么可能导致这些对/negotiate 的重复调用和 404 从中心端点返回?
  • 我们如何在无法访问出现此问题的客户端的情况下进一步调试问题?

更新

我们现在为 @microsoft/signalr 包实现了一个自定义记录器,我们在 configureLogger() 重载中使用它。此记录器登录到我们的 Application Insights,这使我们能够跟踪出现问题的那些客户端的客户端日志。

以下屏幕截图显示了单个客户端的日志条目的简短 sn-p。

我们看到 WebSocket 连接失败(Failed to start the transport "WebSockets" ...)并且使用了备用传输 ServerSentEvents。我们看到日志HttpConnection 连接成功,但在选择ServerSentEvents 传输后大约 15 秒后,发送了一个握手请求,该请求失败并显示来自服务器的消息服务器返回握手错误:握手被取消。之后会发生一些更严重的错误并且连接被关闭。之后,重新建立连接,一切从新开始,15 秒后发生新的握手错误,依此类推。

为什么客户端发送握手请求需要这么长时间?这 15 秒似乎是问题所在,因为这对服务器来说太长了,服务器取消了连接到超时。

我们仍然认为这可能与客户端的网络(代理、防火墙等)有关。

提琴手

我们使用 Fiddler 来阻止 WebSocket 进行测试。正如预期的那样,回退机制启动并且 ServerSentEvents 用作传输。与我们从问题中看到的日志相反,握手请求是立即发送的,而不是在 15 秒后发送。然后一切都按预期工作。

【问题讨论】:

  • 如果可以的话,请在浏览器中提供F12捕获的网络信息截图,让我们分析一下。
  • @JasonPan 不幸的是,这是不可能的,因为我们无法访问发生此问题的客户端。这只发生在我们的部分客户身上。我们无法在我们这边重现这种行为。

标签: azure long-polling asp.net-core-signalr


【解决方案1】:

您应该检查您在项目中使用的定价层,免费或标准。

您应该更改Standard Tier 中的连接字符串。如果您仍使用免费套餐,则存在一些限制。

官方文档:Azure SignalR Service limits

【讨论】:

  • 我们不使用 Azure SignalR 服务。我们只使用Redis backlane for ASP.NET Core SignalR scale-out
  • @M.E.你能告诉我们你的Startup.cs文件没有任何敏感信息吗?
  • @JsonPan 请查看我的更新答案。我们现在可以访问客户端日志记录。
猜你喜欢
  • 1970-01-01
  • 2020-01-12
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
  • 1970-01-01
  • 2013-05-30
相关资源
最近更新 更多