如果客户端异常退出了,我们会从服务端记录用户连接的 _connMap 表中找到改用户,如果它断连了就从此表中删除,并设置其状态为 offline。
因为记录用户连接情况的表是可能被多个线程操作的,所以访问表的操作都要使用互斥锁进行保护。
// 处理客户端异常退出
void ChatService::clientCloseExceptionHandler(const TcpConnectionPtr &conn)
{User user;// 互斥锁保护{lock_guard<mutex> lock(_connMutex);for (auto it = _userConnMap.begin(); it != _userConnMap.end(); ++it){if (it->second == conn){// 从map表删除用户的链接信息user.setId(it->first);_userConnMap.erase(it);break;}}}// 用户注销_redis.unsubscribe(user.getId()); // 更新用户的状态信息if (user.getId() != -1){user.setState("offline");_userModel.updateState(user);}
}
客户端异常退出模块测试
我们先登录用户张三

可以看到数据库显示张三用户是登录的状态

我们使用CTRL + C键模拟客户端异常退出,然后查看数据库情况。可以看到服务端监听到了客户端连接断开的情况,并打印日志。

数据库情况,可以看到断连用户状态被重置为offline。

















