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

举报
看,未来 发表于 2021/08/26 13:19:45 2021/08/26
【摘要】 @[toc] 客户端异常退出此前我们对客户端退出的操作仅仅就是将连接释放掉,但是既然加入了新的业务,受业务影响,客户端的退出就不能是这么简单的处理了。打开 chatserver.cpp ,原先是这样的:void ChatServer::onConnection(const TcpConnectionPtr &conn){ if(!conn->connected()){ //用户断开连接...

请添加图片描述

@[toc]

客户端异常退出

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

打开 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;
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。