zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C++搭建集群聊天室(十一):客户端 || 服务器 异常退出解决方案

2023-09-14 09:15:27 时间

请添加图片描述

客户端异常退出

此前我们对客户端退出的操作仅仅就是将连接释放掉,但是既然加入了新的业务,受业务影响,客户端的退出就不能是这么简单的处理了。

打开 chatserver.cpp ,原先是这样的:

void ChatServer::onConnection(const TcpConnectionPtr &conn){
    if(!conn->connected()){ //用户断开连接
        conn->shutdown();
    }
}

现在是这样的:

void ChatServer::onConnection(const TcpConnectionPtr &conn){
    if(!conn->connected()){ //用户断开连接
        ChatService::instance()->clientCloseException(conn);
        conn->shutdown();
    }
}

打开 chatservice.cpp ,实现 clientCloseException 函数,函数声明该加的自己加。

void ChatService::clientCloseException(const TcpConnectionPtr &conn){
    
    User user;

    {
        //以conn从哈希表中倒查主键id
        lock_guard<mutex> lock(_connMutex);

        
        for(auto it = _userConnMap.begin();it!=_userConnMap.end();){
            if(it->second == conn){
                //更改用户状态
                user.setID(it->first);

                //从hash表删除用户信息
                _userConnMap.erase(it);
                break; 
            }
            else{
                it++;
            }
        }
    }
     
    //数据持久化
    if(user.getID() != -1){
        user.setstate("offline");   //再细一点
    _usermodel.updateState(user);
    }
}

客户端的异常退出影响相对较小,顶多就是一台客户端的再连接异常,但是服务器的异常退出问题就大了,那会是一批客户端的再链接异常。


服务端异常退出

在 usermodel 里面写一个重置的函数。

void UserModel::resetstate()
{
    // 1.组装sql语句
    char sql[1024] = "update user set state = 'offline' where state = 'online'";

    MySQL mysql;
    if (mysql.connect())
    {
        mysql.update(sql);
    }
}

函数声明里面自行配置。


在chatservice中去调用这个方法:

void ChatService::reset(){
    //把所有online状态的用户转为offline
    _usermodel.resetstate();
}

函数声明里面自行配置。


在main函数中设置信号捕捉:

#include<iostream>
#include<signal.h>
#include "chatserver.hpp"
#include "chatservice.hpp"

using namespace std;

void resetHandler(int){	//这个int就算你不用也加上
    ChatService::instance()->reset();
    exit(0);
}

int main(){
		//捕捉 Ctrl+C 信号
    signal(SIGINT,resetHandler);

    EventLoop loop;
    InetAddress addr("127.0.0.1",7000);
    ChatServer server(&loop,addr,"ChatServer");

    server.start();
    loop.loop();
    return 0;
}