我使用以下代码在组中添加用户,并使用以下代码将用户保存在针对此特定组的数据库中。
服务器
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();
}
}
}
}
问题:
假设我使用userid = 1登录roomid = 1和contextid = 123asd。如果我刷新我的窗口,那么contextid将会改变,现在如果我关闭浏览器选项卡然后关注查询:
var item = dc.LoggedInUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
没有找到针对最新connectionid的用户,因为当我在连接时保存用户时,connectionid是不同的。
如何在断开连接事件中为特定用户设置连接状态为false。
提前致谢。
答案 0 :(得分:0)
OnConnected
您应该保存所有connectionIds(与用户映射),connectionId应该是唯一的,而不是用户。因为用户可以同时与信号器建立多个连接(新标签)。
每次你应该在Onconnected
上映射用户和connectionId。每次你应该删除那个connectionId,而不是OnDisconnected
上用户的所有connectionIds。如果{i}不在列表中,则应该将connectionId添加到用户列表中(如果在OnReconnected
上没有调用断开连接,即使用户未断开连接)也应该添加。
您应该根据此重构代码库。首先,您应该删除connectionId。然后,你可以检查;如果该用户没有留下任何记录(使用该connectionId映射),则可以发送消息。
检查here
我已经更改了一些代码,您可以根据这些知识改进此代码。您也应该在AddLoginUser
上致电OnReconnected
。
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();
}
}
}