我在使用 SignalR 和用户在 ASP.NET MVC 4 应用程序中更改身份时遇到问题。我将表单身份验证与自定义成员资格提供程序一起使用。
我拥有 SignalR 的视图也有一个登录(和注销)按钮,并且登录和注销的用户都必须能够查看此视图(并且都连接到与该视图关联的 SignalR 组看法)。但是,当人们登录时,我一直遇到麻烦。当用户身份更改时,“重新连接”底层 SignalR 连接的推荐做法是什么?该视图是其他操作显示的其他几个视图之一。这是唯一包含 SignalR javascript 的。
事实上,我什至对用户的身份都不是很感兴趣,所以以某种方式关闭用户亲和力是可以的(但我找不到这样做的方法)。用户更改触发页面重新加载也可以,因为登录/注销发生在维护连接的窗口之外的窗口中,因此后者没有用户的焦点。
换句话说,问题是:当用户身份从登录用户更改为已注销用户时,我如何保持底层 SignalR 连接继续运行,反之亦然?
我尝试过的事情
处理页面上的登录/注销事件,如下所示:
$("a[href='/Account/Logout']").click(function () { $.connection.hub.stop(); });
这可行,但这将需要在用户能够登录或注销的每个页面上都有 SignalR,而不仅仅是实际使用 SignalR 的页面。
在集线器上添加一个以 ASP.NET 会话 ID 为键的附加组,该组在登录和注销之间保持一致。登录或注销时,我通过向具有该会话 ID 的组发送重新连接触发器来通知客户端。事实证明这为时已晚,在请求结束时身份已经更改,因此引发了异常。
有关我的设置的更多详细信息
对于这个特定的用例,用户会看到一个包含 SignalR 的页面。我像往常一样加入中心:
var hub = $.connection.theNameOfTheHub;
$.connection.hub.start().done(function () {
hub.server.joinList(id);
});
出于本示例的目的,我更改了一些名称。基本上,我想监视页面上显示的项目列表的变化。我使用列表的 id 作为标识符加入了一个组。
异常消息是“ System.InvalidOperationException
:无法识别的用户身份。在活动 SignalR 连接期间,用户身份无法更改。” 它来自Microsoft.AspNet.SignalR.PersistentConnection.GetConnectionId
. 我查找了源,它将实际context.Request.User.Identity.Name
与存储在连接令牌中的源进行了比较。这一切都很有道理,但我正在寻找的是一种解决方法。