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

请添加图片描述

客户端异常退出

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

打开 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;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

看,未来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值