服务器异常退出处理代码和测试

68 阅读2分钟

之前我们完成了客户端异常退出的处理代码,客户端异常退出是因为它没有发出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方法

image.png

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"},并查看数据库

image.png ctrl+c停掉服务器

image.png 再次查看数据库,看看zhang san的state是否被置为offline

image.png