Отключить клиент от серверной стороны signalr

Я использую SignalR 1 с веб-приложением MVC4 С# с аутентификацией формы. У меня есть код на моей странице макета в 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 выдает сообщение об ошибке, если пользователь изменил аутентификацию после входа в систему и соединение осталось. Ошибка:

Идентификатор соединения находится в неправильном формате.

Ответ 1

Вы не можете остановить и запустить соединения 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.

Ответ 2

Один из способов сделать то, что вы просите, - написать сообщение о отключении на вашем клиенте, которое сервер может вызвать через SignalR. Может быть, что-то вроде этого:

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

Затем на сервере что-то вроде этого:

Clients.Client(Context.ConnectionId).serverOrderedDisconnect();

Ответ 3

Попробуйте контролировать все из javascript. Ниже приведен пример выхода из системы, логин будет аналогичным.

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

Если статус аутентификации пользователя изменяется при активном соединении существует, пользователь получит сообщение об ошибке: "Идентификатор пользователя не может измениться во время активного соединения SignalR." В этом случае ваш приложение должно повторно подключиться к серверу, чтобы убедиться, что идентификатор соединения и имя пользователя согласованы. Например, если ваш приложение позволяет пользователю выйти из системы при активном подключении существует, имя пользователя для соединения больше не будет соответствовать имени который передается для следующего запроса. Вы захотите остановить перед тем, как пользователь выйдет из системы, а затем перезапустите его.

Однако важно отметить, что большинству приложений не понадобятся вручную остановить и запустить соединение. Если ваша заявка перенаправляет пользователей на отдельную страницу после выхода из системы, например, поведение по умолчанию в приложении Web Forms или приложении 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();
            });
        });
    });
});

Ответ 4

Попробуйте следующее:

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 в вашем методе действий.

Ответ 5

Если кто-то все еще ищет решение (SignalR версия 2.4.1):

GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>().GetConnections().First(c => c.ConnectionId == "YourId").Disconnect();

Ответ 6

Скопируйте и вставьте следующую функцию в свой концентратор

Use HttpContext.Current.Response.End();

чтобы заставить клиента отключиться в вашем концентраторе