I am using the following code to add user in group and save user in db against this particular group using the following code.
SERVER:
public class ChatHub : Hub
{
public async Task JoinRoom(string user_Id, string room_Id, string user_Name)
{
AddLoginUser(room_Id, this.Context.ConnectionId, user_Id);
await this.Groups.Add(this.Context.ConnectionId, room_Id);
}
public void Connect(string user_Id, string room_Id, string user_Name)
{
var id = Context.ConnectionId;
Clients.Caller.onConnected(id, user_Name, GetRoomUser(room_Id), GetRoomMessage(room_Id));
// send to all in group to update user list
Clients.OthersInGroup(room_Id).onNewUserConnected(id, user_Name);
}
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)
{
item.Connected = false;
dc.SubmitChanges();
Clients.OthersInGroup(item.RoomID.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())
{
var checkUserLogedIn = (from user in dc.LoggedInUsers
where (user.RoomID == Convert.ToInt32(room_Id) && user.UserID == Convert.ToInt32(user_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);
objLoggedInUser.Connected = true;
dc.LoggedInUsers.InsertOnSubmit(objLoggedInUser);
dc.SubmitChanges();
}
else
{
if (!checkUserLogedIn.Connected)
{
checkUserLogedIn.Connected = true;
dc.SubmitChanges();
}
}
}
}
Problem:
Suppose i logged-in with userid=1 for roomid=1 and contextid=123asd. If i refresh my window then contextid will change and now if i closing browser tab then following query:
var item = dc.LoggedInUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
not find out the user against latest connectionid, because when i had saved user on connect at that time connectionid was different.
How i can set connected status false for particular user on disconnect event.
Thanks in advance.
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 onOnDisconnected
. 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) onOnReconnected
.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
onOnReconnected
also.