SignaR可以用来实现服务器向客户端推送信息,但是SignalR的每个Hub的生命周期很短,不能长期停留在内存里。因此,如果服务器想要对客户端推送消息时,应该采用signalR的一个“全局”的上下文来实现。此功能的应用背景是:服务器的数据发生了更新,它希望向所有的用户、某个分组的用户或者是单个用户发送推送消息,而不是由客户端发送请求来检测数据是否有更新。这才是真正的SignalR要做的事!
在Asp.Net有关SignalR的介绍里有提到向所有用户发送推送消息的实现方式(参见:
http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-server-broadcast-with-signalr-20)。但是向分组的用户或单个用户发送消息的实现方式,并没有提供。本文将说明如何向分组推送消息,其他的两种实现很相似。
另外,在我发现Signalr有提供全局机制之前,我采用了让一个Hub长期停留在内存的方式实现。大致意思为:
我需要实现一个Hub,它可以动态地检测数据库数据的变化,然后推送给前端相关的用户。如果直接在继承Hub的类里实现,并调用的话,也就意味着由SignalR创建的所有Hub都要长时间地停留在内存里,而且由于我的推送信息是根据组(Group)进行的。结果导致的问题就是:有太多的Hub停留在内存了;而且针对某个分组的消息,会因为有多个Hub(每个Hub的实现是一样的)而发送多次。
后来,我想到了一个解决这个的办法,就是我只在内存里保留一个Hub的实例。这样就不会出现一条消息多次发送的问题了。具体的做法是: