为啥多次收到此 SignalR 消息?

Posted

技术标签:

【中文标题】为啥多次收到此 SignalR 消息?【英文标题】:Why is this SignalR messages being received multiple times?为什么多次收到此 SignalR 消息? 【发布时间】:2021-12-08 11:47:58 【问题描述】:

我在 Blazor 服务器端应用程序中使用 SignalR。我在项目中添加了Microsoft.AspNetCore.SignalR.Client Nuget 包(v5.0.11),并使用以下代码创建集线器连接...

HubConnection hubConnection = new HubConnectionBuilder()
  .WithUrl("url")
  .Build();
await hubConnection.StartAsync();

然后我发送一条带有以下代码的消息(添加Debug.WriteLine 以确认发生了什么)...

Debug.WriteLine($"DateTime.Now.ToLongTimeString() SignalR msg sent");
await hubConnection.SendAsync("Send", "Hello");

处理此类消息的组件创建集线器连接并连接到On 处理程序,如下所示...

HubConnection hubConnection = new HubConnectionBuilder()
  .WithUrl("url")
  .Build();
hubConnection.On<string>("Receive", msg =>
  Debug.WriteLine($"DateTime.Now.ToLongTimeString() SignalR msg received - msg"));
await hubConnection.StartAsync();

当消息发出时,它肯定只发送一次(我可以从输出面板确认,我只看到“发送”输出一次),但收到两次。

四处搜索,似乎一个常见的原因是 jQuery 被加载了两次。但是,我已经检查了这一点,但事实并非如此。它只被加载一次。此外,团队中的其他开发人员之一尝试了它,他收到了 15 次消息!即使我们不小心包含了 jQuery 两次,我们当然也没有包含 15 次。此外,他使用的代码与我完全相同(从源代码管理中签出),所以如果这是问题所在,我们应该得到相同的结果。

有人知道为什么会发生这种情况吗?谢谢

【问题讨论】:

检查您对 hubConnection 的处理。如果它在组件 init 上构造并且未释放,则您可能有多个实例。 @BrianParker 太棒了!这就是问题所在。您想将其添加为答案,我会接受。非常感谢。 问题:您要连接到的SignalR 集线器是否在托管 Blazor 服务器端的同一服务器上?如果是这样,您创建了一个完全不必要的设置:一个带有客户端的页面,在服务器上运行,连接到 SignalR 集线器也在同一台服务器上运行?跨度> @Quango 是的,它们在同一台服务器上,但是如果我不创建连接,如何向客户端发送消息?我认为这就是 SignalR 的全部意义所在。 @AvrohomYisroel 我会把我的答案放在下面,这样就很清楚了(另外我不能在 cmets 中插入图表)。 【参考方案1】:

当您在组件中初始化 HubConnection 并且未在组件上配置 IDisposeIAsyncDispose 以处置 HubConnection 时,可能会发生这种情况。

【讨论】:

【参考方案2】:

在 Blazor 服务器端应用程序中,已经有一个 SignalR 主机将更新推送到客户端。

如果您想从页面推送更新,您可以使用Singleton Service 来处理通信。

如果您设置自己的 SignalR 集线器并在组件中使用 SignalR 客户端,则您的应用程序类似于下图:

如您所见,客户端实际上是在服务器上运行的。您添加的 SignalR 集线器会增加处理和内存开销,但不会增加任何价值。

我创建了一个简单的示例应用程序,它使用客户端侦听更新的服务: https://github.com/conficient/BlazorServerWithSignalR

【讨论】:

谢谢。我确实想知道为什么我需要在 Blazor 已经使用 SignalR Nuget 包时添加它,但是如果您查看 Microsoft 文档,那正是他们所做的。您知道使用 Nuget 包是否比您所展示的方式有任何好处吗? 我直接在 Blazor 服务器上使用 SignalR 的唯一原因是如果我需要在客户端或其他不使用 Blazor 的客户端上执行任何 JS 谢谢。对我来说,Blazor 的主要好处之一是我很少需要编写 JS,所以我想我可能不需要完整的 SignalR。话虽如此,SignalR 确实还有其他一些好处,例如只发送给某些订阅者或组,但如果我不需要(大多数时候),那么我想没有必要使用包裹。再次感谢。

以上是关于为啥多次收到此 SignalR 消息?的主要内容,如果未能解决你的问题,请参考以下文章

SignalR 2.2 客户端未收到任何消息

SignalR入门篇

从服务器错误收到的 Signalr 关闭消息

为啥我在使用 isNull 时收到此错误消息

为啥我收到此消息“Telerik 未定义”?

从 signalR 更新后如何重新加载我的表