desconectar el cliente del señalizador del lado del servidor

I'm using SignalR 1 with MVC4 C# web application with form authentication. I have a code in my layout page in JavaScript :

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

I want to disconnect a user form the hub and start connect again after he does a login and validate ok. I want to do it from server side inside my account controller and method :

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     
}

The reason I want to do it is because SignalR throws an error if user changed to authenticated after login and the connection remains . The error is:

El ID de conexión tiene un formato incorrecto.

preguntado el 08 de abril de 13 a las 22:04

7 Respuestas

You cannot stop and start SignalR connections from the server. You will need to call

$.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.

Respondido el 07 de enero de 14 a las 20:01

I call "$.connectino.hub.start();" on every document ready state..is it OK to call "$.connection.hub.stop();" before ? - haddar macdasi

You are going to have to get it from the client when the user connects to the hub, and store it to be able to compare it against any new connections, this will also prevent impersonation attacks. - Kelso Sharp

What happens if an employee has just gotten fired and they need their access revoked? I need to be able to disconnect any open signalR sessions. There has to be a way. - Cerebro2000

One way you could do what you ask is to write a disconnect event on your client that the server can call through SignalR. Maybe something somewhat like this:

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

Then, on the server, something like this:

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

respondido 23 mar '15, 09:03

but how can I get the Context.ConnectionId from server side code inside the "LogOn" action ? - haddar macdasi

If someone is still looking for solution(SignalR version 2.4.1):

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

Respondido 17 Jul 19, 20:07

How do you do it in aspnetcore? - bboyle1234

Sorry, but i have used only asp.net - Лопатка Подзаборная

Try controlling everything from javascript. The following is a logout example, login would be similar.

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

If a user's authentication status changes while an active connection exists, the user will receive an error that states, "The user identity cannot change during an active SignalR connection." In that case, your application should re-connect to the server to make sure the connection id and username are coordinated. For example, if your application allows the user to log out while an active connection exists, the username for the connection will no longer match the name that is passed in for the next request. You will want to stop the connection before the user logs out, and then restart it.

However, it is important to note that most applications will not need to manually stop and start the connection. If your application redirects users to a separate page after logging out, such as the default behavior in a Web Forms application or MVC application, or refreshes the current page after logging out, the active connection is automatically disconnected and does not require any additional action.

The following example shows how to stop and start a connection when the user status has changed.

<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();
            });
        });
    });
});

Respondido el 09 de diciembre de 14 a las 18:12

Prueba esto:

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();
        }
}

Assuming your connection handle is connection. The challenge is accessing a handle to your connection object in your Action Method.

respondido 23 mar '15, 09:03

but how can I get the "connection" object from server side code inside the "LogOn" action ? - haddar macdasi

good question. didn't think this thru well. It probably wouldn't be readily available unless you added it to session, which seems wrong... - David Alperovich

You can the hub context to abort() the connection directly in .Net Core

Context.Abort();

See the method below

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

contestado el 22 de mayo de 21 a las 01:05

Copy and paste the following function into your Hub

Use HttpContext.Current.Response.End();

to force the client to disconnect in your hub

Respondido el 24 de junio de 16 a las 07:06

Grammatical & presentation issues aside, are there any technical issues with this solution that would cause the downvotes? - Sinfonía sinestésica

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.