14

我将 SignalR 1 与带有表单身份验证的 MVC4 C# Web 应用程序一起使用。我的布局页面中有一段 JavaScript 代码:

$(documnet).ready(function(){
       connect to hub code ...
})

我想断开用户与集线器的连接,并在他登录并验证成功后再次开始连接。我想从我的帐户控制器和方法中的服务器端执行此操作:

public ActionResult LogOn(LoginModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        if (System.Web.Security.Membership.ValidateUser(model.UserName, model.Password))
        {
            FormsAuthentication.SetAuthCookie(model.UserName, false);
            ....here , disconnect from hub
            ....to make the user reconnect     
}

我想这样做的原因是,如果用户在登录后更改为经过身份验证并且连接仍然存在,SignalR 会引发错误。错误是:

连接 ID 的格式不正确。

4

7 回答 7

26

您无法从服务器停止和启动 SignalR 连接。你需要打电话

$.connection.hub.stop(); //on the client before the user attempts to log on and then call 
$.connection.hub.start(); //after the log on attempt has completed.
于 2013-04-09T07:19:57.693 回答
12

您可以按照您的要求做的一种方法是在您的客户端上编写一个断开连接事件,服务器可以通过 SignalR 调用该事件。也许有点像这样:

myHub.client.serverOrderedDisconnect = function (value) {
    $.connection.hub.stop();
};

然后,在服务器上,是这样的:

Clients.Client(Context.ConnectionId).serverOrderedDisconnect();
于 2013-04-09T23:12:00.967 回答
6

如果有人仍在寻找解决方案(SignalR 2.4.1 版):

GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>().GetConnections().First(c => c.ConnectionId == "YourId").Disconnect();
于 2019-07-17T19:49:10.927 回答
4

尝试从 javascript 控制一切。以下是注销示例,登录类似。

http://www.asp.net/signalr/overview/security/introduction-to-security

如果用户的身份验证状态在活​​动连接存在时发生更改,则用户将收到一条错误消息,指出“在活动 SignalR 连接期间用户身份无法更改”。在这种情况下,您的应用程序应该重新连接到服务器,以确保连接 ID 和用户名是协调的。例如,如果您的应用程序允许用户在活动连接存在时注销,则连接的用户名将不再与为下一个请求传入的名称匹配。您需要在用户注销之前停止连接,然后重新启动它。

但是,重要的是要注意大多数应用程序不需要手动停止和启动连接。如果您的应用程序在注销后将用户重定向到单独的页面,例如 Web 窗体应用程序或 MVC 应用程序中的默认行为,或者在注销后刷新当前页面,则活动连接将自动断开并且不需要任何其他操作。

以下示例显示了如何在用户状态发生更改时停止和启动连接。

<script type="text/javascript">
$(function () {
    var chat = $.connection.sampleHub;
    $.connection.hub.start().done(function () {
        $('#logoutbutton').click(function () {
            chat.connection.stop();
            $.ajax({
                url: "Services/SampleWebService.svc/LogOut",
                type: "POST"
            }).done(function () {
                chat.connection.start();
            });
        });
    });
});

于 2014-12-09T18:03:08.257 回答
1

试试这个:

public ActionResult LogOn(LoginModel model, string returnUrl) {
    if (ModelState.IsValid) {
        if (System.Web.Security.Membership.ValidateUser(model.UserName, model.Password)) {
            FormsAuthentication.SetAuthCookie(model.UserName, false);
            connection.Stop();
        }
}

假设您的连接句柄是connection. connection挑战是在 Action Method 中访问对象的句柄。

于 2013-04-10T21:58:54.597 回答
0

您可以在 .Net Core 中直接使用集线器上下文中止()连接

Context.Abort();

看下面的方法

https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.signalr.hubcallercontext.abort

于 2021-05-22T00:45:00.120 回答
-7

将以下函数复制并粘贴到您的 Hub 中

Use HttpContext.Current.Response.End();

强制客户端在您的集线器中断开连接

于 2016-06-23T14:45:53.927 回答