我有两个关于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();
NotificationProcessor
然后使用IHubProxy
对象来调用集线器中的方法。
我发现每次HubConnection
实例化时创建NotificationProcessor
对象,并且在完成时不放置HubConnection
会导致内存泄漏。
问题
(1)为了避免内存泄漏,我需要以某种方式处理HubConnection
。我读到我能做到
Task.Run(() => this.HubConnection.Stop())
这个问题是我不知道在什么时候我可以称之为。由于使用代理调用hub方法是异步的,我可以在调用hub方法后立即调用它吗?或者,如果从集线器向前端客户端发送通知有延迟,这会导致问题吗?
我想另一种选择是将HubConnection初始化包含在using语句中,如此
using (HubConnection connection = new HubConnection(serverUrl))
{
}
我听说这也有问题,因为处理HubConnection
可能需要一段时间。
有没有比另一个更好的?后者似乎更惯用,而前者更明确,可能更好。
(2)为每个创建的HubConnection
实例创建NotificationProcessor
是不是一个好主意?有没有办法坚持这种联系(即,使其静止或类似)?我对对象生命周期和副作用有一个不稳定的理解,特别是因为这个应用程序部署在云上,我不知道一个HubConnection
实例被多次使用意味着什么。它是在线程之间共享的吗?节点之间(我使用的是Redis背板)?用户之间?如果在每次需要发送数据时保持实例化是很昂贵的话,保持连接打开是有意义的,但是当我在多个节点上部署在云上时,我只是不明白它是如何工作的。每次建立新连接似乎更容易。
答案 0 :(得分:3)
这个问题是在不久前发布的,但看不到回应,我以为我会插话。
鉴于您所描述的内容,我个人建议为每个处理器重新使用HubConnection的静态实例,并为每个处理器添加一个新的HubProxy。只需确保处理器处理后IHubProxy可以正确处理。
每个连接都将被视为SignalR Hub的单独客户端,因此如果您需要在同一进程中使用单独的通知或客户端,则需要单独的连接,但在您的情况下,所有这些通知都来自同一个客户。
请务必查看HubConnection。
的主题安全性线程安全
任何公共静态(在Visual Basic中共享)成员 这种类型是线程安全的。任何实例成员都不能保证 是线程安全的。