之前我们完成了客户端异常退出的处理代码,客户端异常退出是因为它没有发出json字符串连接就断开了,服务器检测到连接断开后需要删除_userConnMap中用户对应的connection以及更改user表的state字段
但是服务器异常退出了,user表的用户的状态还是online,这个问题还没有解决。因为我们Ctrl C强制退出服务器的时候,服务器根本没有机会更改数据库里用户的state信息
我们使用信号处理机制,在main函数里,服务器启动前注册信号处理函数,当捕获SIGINT信号时,会执行我们注册的resetHandler
函数,进行user表state的重置,
1. 完善src/server/main.cpp
#include "chatserver.hpp"
#include "chatservice.hpp"
#include <iostream>
#include <signal.h>
using namespace std;
// 处理服务器ctrl c结束的方法
void resetHandler(int)
{
ChatService::instance()->reset();
exit(0);
}
int main()
{
// 注册信号处理函数
signal(SIGINT, resetHandler);
EventLoop loop;
InetAddress addr("127.0.0.1", 6000);
ChatServer server(&loop, addr, "ChatServer");
server.start();
loop.loop();
return 0;
}
2. 在业务层include/server/chatservice.hpp中添加reset函数
//服务器异常,业务重置方法
void reset();
3. 在业务层src/server/chatservice.cpp中使用ORM类访问数据库,添加代码如下:
//服务器异常,业务重置方法
void ChatService ::reset()
{
//把online状态的用户设置成offline
_userModel.resetState();
}
4. 在usermodel.hpp中添加resetState方法
5. usermodel.cpp中实现resetState方法
//重置用户的状态信息
void UserModel::resetState()
{
// 1. 组装sql语句
char sql[1024] = "update user set state = offline where state = 'online'";
MySQL mysql;
if (mysql.connect()) // 2. 连接数据库
{
mysql.update(sql);
}
}
6. 编译测试
编译成功后登录zhang san : {"msgid":1,"id":27,"password":"123456"}
,并查看数据库
ctrl+c停掉服务器
再次查看数据库,看看zhang san的state是否被置为offline