标签: signalr-hub

内存泄漏问题:如何处置 SignalR hub 连接以及何时创建新连接

我有两个有关 SignalR 集线器连接的相关问题,但在讨论它们之前,我将仅提供一些有关我正在做的事情的背景信息。

语境

我有一个使用 SignalR 将通知从服务器发送到前端(Javascript)客户端的应用程序。但是,还有一个后端 (.NET) 客户端可以创建中心的代理。后端客户端处理通知并将其发送到集线器,然后集线器将这些通知发送到前端客户端。

更具体地说,我有一个通知处理类,我们称之为NotificationProcessor.cs。每次创建新通知时,NotificationProcessor都会实例化一个实例。实例化后NotificationProcessor,将设置与集线器的代理连接。我有一个类,HubProxyService.cs它创建HubConnection对象并IHubProxy从中创建对象。其片段如下:

this.HubConnection = new HubConnection(serverUrl);
this.HubProxy = HubConnection.CreateHubProxy(hubName);
Task t = Task.Run(() => this.HubConnection.Start(new LongPollingTransport()));
t.WaitAndUnwrap();
Run Code Online (Sandbox Code Playgroud)

NotificationProcessor然后使用该IHubProxy对象调用集线器中的方法。

我发现HubConnection每次创建对象都会被实例化,并且在完成后NotificationProcessor不处理会导致内存泄漏。HubConnection

问题

(1)为了避免内存泄漏,我需要HubConnection以某种方式进行处置。我读到我可以做到

Task.Run(() => this.HubConnection.Stop())
Run Code Online (Sandbox Code Playgroud)

问题是我不知道什么时候可以调用它。由于使用代理调用 hub 方法是异步的,我可以在调用 hub 方法后立即调用它吗?或者,如果从集线器向前端客户端发送通知出现延迟,这是否会导致问题?

我想另一种选择是将 HubConnection 初始化包装在 using 语句中,如下所示

using (HubConnection connection = new HubConnection(serverUrl))
{

}
Run Code Online (Sandbox Code Playgroud)

我听说这也可能有问题,因为处理HubConnection可能需要一段时间。

有一个比另一个更好吗?后者似乎更惯用,而前者更明确并且可能效果更好。

(2) 为创建的HubConnection每个实例创建 …

c# memory-leaks signalr signalr-hub

3
推荐指数
1
解决办法
5272
查看次数

SignalR Core 如何每 n 秒向客户端发送消息

又名“从后台服务向客户端发送消息”

我希望我的 SignalR 服务器每 n 秒更新一次仪表板。我现在正在使用这个:

public class MyHub : Hub
{
    public override Task OnConnectedAsync()
    {
        Observable.Interval(TimeSpan.FromSeconds(0.5)).Subscribe(l =>
        {
            var alt = CalcAltitude(l);
            SendMessage(alt);
        });

        return Task.CompletedTask;
    }

    private void SendMessage(double alt)
    {
        Clients.All.SendAsync("SendAction", new Status() {Altitude = alt});
    }

    private double CalcAltitude(long l)
    {
        return 100 * Math.Sin((double) l / 100) + 200;
    }
}

public class Status
{
    public double Altitude { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当我的代码被执行时,它抛出一个异常说

无法访问已处置的对象

我怀疑我在这里做错了什么。

那么,及时向所有客户端发送消息的正确方法是什么?

.net c# signalr signalr-hub

3
推荐指数
1
解决办法
2403
查看次数

从 Controller .Net Core 2.1 调用 Signalr 方法

我正在尝试从 (ASP.NET Core) MVC 控制器调用信号集线器类中的方法,但我无法在网上找到演示如何操作的示例。

注意:有很多示例在 .Net 框架中使用旧版本的信号器,但我看不到任何示例都显示了如何在 .Net Core 中执行此操作。

我需要将 MVC 操作结果中的 id 直接传递到我的集线器,而不是将 id 传递到页面,然后必须将客户端连接返回到集线器。

public class ChatHub : Hub
{ 
    public async Task DoSomething(int id)
    {            
        //// Something in here.
    }
}



public class HomeController : Controller
{
    private readonly IHubContext<ChatHub> _hubContext;

    public HomeController(IHubContext<ChatHub> hubContext)
    {
        _hubContext = hubContext;
    }

    public async Task<ActionResult> Index(int id) 
    {

         //// Call the DoSomething method from here, passing the id across.
         await _hubContext.Clients.All.SendAsync("AddToGroup", groupId);
    }
}
Run Code Online (Sandbox Code Playgroud)

请问有没有办法做到这一点?(或者我是否以错误的方式看待这个问题,是否有更好的方法来实现相同的结果?)

更新:如果我将 Id …

c# signalr signalr-hub asp.net-core-mvc asp.net-core-signalr

3
推荐指数
1
解决办法
4925
查看次数

SignalR 向组中的所有客户端发送消息(少数客户端除外)

我正在使用 SignalR DotNetCore,我创建了组,我需要向组中的所有客户端发送消息,除了具有 Connection Id 的特定客户端。

signalr signalr-hub .net-core asp.net-core-signalr

3
推荐指数
1
解决办法
2524
查看次数

使用 HubContext 进行单元测试 .net core 2.2 SignalR hub 问题

我有一个 SignalR 集线器,我希望对其进行单元测试。该集线器非常简单,只是它在构造函数中包含一个 IHubContext 参数。我遇到的问题是,任何对 UpdateData 方法进行单元测试以便我可以验证 DataModel 数据属性是否已更新的尝试都会因空引用异常而失败。到目前为止,我只能验证该方法是否被调用。是不是我没有正确模拟 HubContext 依赖项?

任何人都可以提供如何解决此问题的详细信息吗?

using Microsoft.AspNetCore.SignalR;
using Moq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace Tests
{
    public class DataModel
    {
        public string Name { get; set; }
        public string Job { get; set; }

    }

    public class DataHub : Hub
    {
        private readonly IHubContext<DataHub> _hubContext;

        private DataModel data;

        public DataHub(IHubContext<DataHub> context)
        {
            _hubContext = context;
        }

        public override async Task OnConnectedAsync()
        {
            await Groups.AddToGroupAsync(Context.ConnectionId, "DataGroup");
        }

        public void UpdateData(DataModel update)
        { …
Run Code Online (Sandbox Code Playgroud)

moq xunit signalr-hub asp.net-core

3
推荐指数
1
解决办法
5277
查看次数

通过 SignalR 发送不同对象的列表

通过 SignalR 向客户端发送不同对象列表的最佳方式是什么?

当我使用具有相同基类的对象列表时,客户端仅接收基类的属性:

class Update { }
class UpdateA { public string PropertyA {get; set;}}
class UpdateB { public string PropertyB {get; set;}}
...
IEnumerable<Update> updates = GetUpdates();
await Clients.Caller.SendAsync("update", updates);
Run Code Online (Sandbox Code Playgroud)

当我使用字符串形式的预序列化数据时,序列化器将 json 数据转义为字符串。

IEnumerable<string> updates = GetUpdates();
await Clients.Caller.SendAsync("update", updates);
// data looks like: [ "{...}", "{...}" ]
Run Code Online (Sandbox Code Playgroud)

我必须编写自己的序列化程序吗?SignalR 在 dotnet core 中如何工作?

c# signalr-hub .net-core asp.net-core-signalr

3
推荐指数
1
解决办法
3383
查看次数

SignalR:根据验证程序,远程证书无效:RemoteCertificateNameMismatch

我在 .Net 5 中有一个 Blazor 服务器应用程序,它工作正常。最近,我添加了一个用于通知消息的 SignalR HubConnection,但由于在生产服务器中建立了 SSL 连接,我遇到了异常,如下所示:

Workflow2.Common.DalException: The SSL connection could not be established, see inner exception.
 ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure: RemoteCertificateNameMismatch
   at System.Net.Security.SslStream.SendAuthResetSignal(ProtocolToken message, ExceptionDispatchInfo exception)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean async, Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
[2022-01-26 13:07:30.970][ERR]: InnerException Message
System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure: …
Run Code Online (Sandbox Code Playgroud)

ssl-certificate signalr-hub blazor-server-side

3
推荐指数
1
解决办法
2676
查看次数

SignalR长轮询运输

我正在使用带有集线器的SignalR 0.5.3,我明确地将传输设置为长轮询,如下所示:

$.connection.hub.start({ transport: 'longPolling' }, function () {
    console.log('connected');
});
Run Code Online (Sandbox Code Playgroud)

使用这样的配置(在global.asax.cs Application_Start方法中):

GlobalHost.DependencyResolver.UseRedis(server, port, password, pubsubDB, "FooBar");
GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(2);
GlobalHost.Configuration.KeepAlive = TimeSpan.FromSeconds(15);
Run Code Online (Sandbox Code Playgroud)

然而,长期轮询似乎既不适用于开发(IIS express)也不适用于生产(IIS 7.5)环境.连接似乎正常,但长轮询请求总是超时(约2分钟后),之后重新连接.IIS的日志在这里.第一次超时请求的回复:

{"MessageId":"3636","Messages":[],"Disconnect":false,"TimedOut":true,"TransportData":{"Groups":["NotificationHub.56DDB6692001Ex"],"LongPollDelay":0}}
Run Code Online (Sandbox Code Playgroud)

超时重新连接响应如下所示:

{"MessageId":"3641","Messages":[],"Disconnect":false,"TimedOut":true,"TransportData":{"Groups":["NotificationHub.56DDB6692001Ex"],"LongPollDelay":0}}
Run Code Online (Sandbox Code Playgroud)

对于这个问题,我将不胜感激.谢谢.

编辑

如果重新连接意味着新的长轮询周期的开始,为什么在global.asax.cs中的KeepAlive设置设置为15秒后~2分钟后启动?问题在于我在IIS前面有一个反向代理,它在25秒后超时保持活动请求,因此当达到此反向代理超时时,我得到504响应.

asp.net long-polling signalr signalr-hub

2
推荐指数
1
解决办法
2万
查看次数

信号中心在独立的Dll中

我在控制台应用程序中托管了一个集线器,并连接了一个WPF应用程序.它运作得很好.然后我将集线器移动到一个单独的项目中,并将主机的引用添加到新项目中.现在我收到500错误,没有其他细节.

为了从另一个汇编/命名空间托管集线器,是否需要做任何不同的事情?

编辑:打开问题后我尝试了一些事情.这是我到目前为止所尝试的:

  • 设置HubName属性.- 不工作.
  • 将完整的命名空间+类传递给HubConnection.CreateHubProxy.- 不工作.
  • 将我的集线器类放入同一个项目但是使用不同的命名空间. - 这很有效.

这是传回的异常."System.Net.WebException:远程服务器返回错误:(500)内部服务器错误.位于Microsoft.AspNet.SignalR.Client.Http.HttpHelper的System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult).<> c_ DisplayClass2 System.Threading.Tasks.TaskFactory 1.FromAsyncCoreLogic(IAsyncResult iar, Func2中的.b _0(IAsyncResult ar)endFunction,Action 1 endAction, Task1 promise,Boolean requiresSynchronization)"

signalr signalr-hub

2
推荐指数
1
解决办法
3891
查看次数

使用SignalR手动创建组

我有一个连接到的userDetails列表,hub我将这些用户存储到List<UserDetails>。我想将一些用户添加Group到,并向该组广播消息。但是我不知道如何创建一个小组,这是我到目前为止所做的:

foreach(var user in userDetails)
{
      Groups.Add(user.connectionId, "Connected");
}
Clients.Group("Connected").broadcastMessage(message);
Run Code Online (Sandbox Code Playgroud)

signalr signalr-hub

2
推荐指数
1
解决办法
1052
查看次数