前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++搭建集群聊天室(十一):客户端 || 服务器 异常退出解决方案

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

作者头像
看、未来
发布2021-09-18 15:06:48
9530
发布2021-09-18 15:06:48
举报
文章被收录于专栏:CSDN搜“看,未来”
请添加图片描述
请添加图片描述

文章目录

客户端异常退出

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

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

代码语言:javascript
复制
void ChatServer::onConnection(const TcpConnectionPtr &conn){
    if(!conn->connected()){ //用户断开连接
        conn->shutdown();
    }
}

现在是这样的:

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

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

代码语言:javascript
复制
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 里面写一个重置的函数。

代码语言:javascript
复制
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中去调用这个方法:

代码语言:javascript
复制
void ChatService::reset(){
    //把所有online状态的用户转为offline
    _usermodel.resetstate();
}

函数声明里面自行配置。


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

代码语言:javascript
复制
#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;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/08/17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 客户端异常退出
  • 服务端异常退出
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档