disconnect client from server side signalr

2020-07-02 12:28发布

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:

The connection id is in the incorrect format.

6条回答
▲ chillily
2楼-- · 2020-07-02 12:36

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();
查看更多
做自己的国王
3楼-- · 2020-07-02 12:40

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

GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>().GetConnections().First(c => c.ConnectionId == "YourId").Disconnect();
查看更多
小情绪 Triste *
4楼-- · 2020-07-02 12:42

Copy and paste the following function into your Hub

Use HttpContext.Current.Response.End();

to force the client to disconnect in your hub

查看更多
Root(大扎)
5楼-- · 2020-07-02 12:46

Try this:

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.

查看更多
家丑人穷心不美
6楼-- · 2020-07-02 12:51

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

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

查看更多
我欲成王,谁敢阻挡
7楼-- · 2020-07-02 12:57

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.
查看更多
登录 后发表回答