SignalR将通知推送到单个经过身份验证的用户的所有浏览器实例

时间:2012-04-10 13:06:01

标签: javascript notifications signalr

我正在处理一个需要在收到新通知时通知用户的应用程序。该应用程序将托管在Azure上,并且将是.NET MVC 3(可能不重要,但仅供参考)。我也

通知保存在MSSQL数据库(2008)中,并且具有IsRead字段。通知是从各种用户和服务器操作生成的。根据用户首选项,将使用IsRead == false创建一些通知。

我有2种不同的场景,我觉得SignalR在处理方面会很完美,我只需要一些指导:

  1. 用户有几个窗口打开浏览网站,并添加了一个新的通知行,分配给该用户IsRead == true
    • 我希望所有特定用户的浏览器实例都有一个特定的js函数来调用以显示弹出的通知
  2. 用户打开了几个窗口并单击弹出的通知。
    • 我希望所有特定用户的浏览器实例都有一个特定的js函数调用来删除弹出的通知。 (只有处理点击的特定浏览器实例也会执行js函数来显示通知详细信息)
  3. 我尝试了什么


    对于第一个场景,我认为导致通知写入数据库的相同操作将负责通知所有用户的浏览器实例。

    第二种情况类似,通过单击弹出窗口,将通过Ajax调用服务器端点,该端点将更新数据库以将通知标记为已读,然后通知所有其他用户的浏览器实例。

    如果有办法根据ASP.NET Forms Authentication Username跟踪SignalR客户端,那么我认为这将解决两种情况下的问题。

    TL; DR


    我的主要问题是我不知道如何使用SignalR向所有特定用户的浏览器实例发出信号。我正在考虑根据ASP.NET Forms Authentication Username创建一个组。这会有用吗? SignalR中是否有一种更简单的方法来处理这个问题?

1 个答案:

答案 0 :(得分:16)

您建立一个以用户名作为密钥的组的电话是好的,我认为这是最快的实施。您可以通过订阅以下内容每次加载页面时调用函数(并且 ConnectionId 已更改):

$.connection.hub.start(function () {
    yourHub.register();
});

在Code背后的中心:

public void Register()
{
    AddToGroup(username);
}

当你想刷新客户的屏幕时,你会这样做:

Clients[username].refreshClientScreen();

其中 refreshClientScreen()是你的javascript函数,用于在浏览器中隐藏通知。

另一种方法是在每个请求上检查 ConnectionId ,并在一个地方注册并保留用户在服务器上的连接。当您需要更新它们时,您可以在每个代码上使用此代码:

Clients[ConnectionId].refreshClientScreen();

您可以在Hub的 Context 对象中找到 ConnectionId

我认为第二种方法难以实现,因为您必须管理保存 ConnectionId -s的位置并通过实施IDisconnect订阅Disconnect事件,以便您可以保留 ConnectionId -s列出最新的,所以我选择第一种方法 - 带有组的方法。