Signalr(V2.2.0) Ondisconnected Set User Offline

SignalR(v2.2.0) OnDisconnected set user offline

OnConnected you should save all connectionIds (which is mapped with user), connectionId should be unique, not the user. Because a user can have more than one connection to signalr at the same time(New Tabs).

Everytime you should map user and connectionId on Onconnected. Everytime you should just remove that connectionId, not all connectionIds of user on OnDisconnected. You should add connectionId with user if it's not in list(if stop called is not called disconnected can occur even user is not disconnected) on OnReconnected.

You should refactor your code base on this. First, you should remove connectionId. Then, you can check; if there is no record left with this user(which is mapped with that connectionId) on list, you can send message.

Check here

I have changed your code a bit, you can improve this code based on this knowledge. You should call AddLoginUser on OnReconnected also.

     public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
{
using (DataContext dc = new DataContext())
{
var item = dc.LoggedInUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
if (item != null)
{
dc.LoggedInUsers.Remove(item);
dc.SubmitChanges();
//If there is no other connection left with this user in this room send message.
if (!dc.LoggedInUsers.Any(x => x.RoomID==item.RoomID && x.userId==item.UserId)
Clients.OthersInGrouproomId.ToString()).onUserDisconnected(Context.ConnectionId, item.UserMaster.User_Name);
}
return base.OnDisconnected(stopCalled);
}
}
}

private void AddLoginUser(string room_Id, string connection_Id, string user_Id)
{
using (DataContext dc = new DataContext())
{
//Just check connectionId uniqunes. You don't need connected field.
var checkUserLogedIn = (from user in dc.LoggedInUsers
where user.ConnectionId == connection_Id
select user).SingleOrDefault();
if (checkUserLogedIn == null)
{
LoggedInUser objLoggedInUser = new LoggedInUser();
objLoggedInUser.ConnectionId = connection_Id;
objLoggedInUser.UserID = Convert.ToInt32(user_Id);
objLoggedInUser.RoomID = Convert.ToInt32(room_Id);
dc.LoggedInUsers.InsertOnSubmit(objLoggedInUser);
dc.SubmitChanges();
}
}
}

SignalR OnDisconnected - a reliable way to handle User is Online for chatroom?

Try following this sample here:

https://github.com/DamianEdwards/NDCLondon2013/tree/master/UserPresence

OnDisconnect and Logged on Users after recycle?

The best way to solve this problem is to log everyone out on application start, aka in your case invalidate/delete all logged in token rows. Therefore whenever the server comes up the application is in a fresh state with no one logged in.

Handle onDisconnected() method of 1.x to SignalR 2.1.2

In version 2.x, Connection events return Task taking an input parameter of bool stopCalled. You simply need to update your method to return task, which is returned by base.OnDisconnected(stopCalled).

Documentation

public override Task OnDisconnected(bool stopCalled)
{
// Add your own code here.
// For example: in a chat application, mark the user as offline,
// delete the association between the current connection id and user name.
return base.OnDisconnected(stopCalled);
}

EDIT

I believe the current SignalR documentation may actually erroneously be advising you to use OnDisconnected() without a bool stopCalled parameter. However, looking at the source for HubBase (which Hub inherits from), you can find the OnDisconnected method declared as the following in 2.x.

/// <summary>
/// Called when a connection disconnects from this hub gracefully or due to a timeout.
/// </summary>
/// <param name="stopCalled">
/// true, if stop was called on the client closing the connection gracefully;
/// false, if the connection has been lost for longer than the
/// <see cref="Configuration.IConfigurationManager.DisconnectTimeout"/>.
/// Timeouts can be caused by clients reconnecting to another SignalR server in scaleout.
/// </param>
/// <returns>A <see cref="Task"/></returns>
public virtual Task OnDisconnected(bool stopCalled)
{
return TaskAsyncHelper.Empty;
}


Related Topics



Leave a reply



Submit