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.
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.
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();
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();
});
});
});
});
If someone is still looking for solution(SignalR version 2.4.1):
GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>().GetConnections().First(c => c.ConnectionId == "YourId").Disconnect();
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.
Copy and paste the following function into your Hub
Use HttpContext.Current.Response.End();
to force the client to disconnect in your hub