当前位置: 首页 > article >正文

集群聊天服务器(8)用户登录业务

目录

  • 登录状态
  • 业务层代码
  • 数据模型层代码
  • 记录用户的连接信息以及线程安全问题
  • 客户端异常退出业务

登录状态

在这里插入图片描述
在这里插入图片描述
登录且状态变为online
在这里插入图片描述

业务层代码

#include "chatservice.hpp"
#include "public.hpp"
#include <string>
#include <muduo/base/Logging.h>
#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>
using namespace muduo;
using namespace std;

//获取单例对象的接口函数
ChatService* ChatService::instance()
{
    static ChatService service;
    return &service;
}

//注册消息以及对应的Handler回调操作
ChatService::ChatService()
{
    //要想实现回调就需要先进行注册,通过绑定对象
    _msgHandlerMap.insert({LOGIN_MSG,std::bind(&ChatService::login,this,_1,_2,_3)});
    _msgHandlerMap.insert({REG_MSG,std::bind(&ChatService::reg,this,_1,_2,_3)});

}

//获取消息对应的处理器
MsgHandler ChatService::getHandler(int msgid)
{
    //记录错误日志,msgid没有对应的事件处理回调
    auto it=_msgHandlerMap.find(msgid);
    if(it==_msgHandlerMap.end())
    {
        //返回一个默认的处理器,空操作
        return [=](auto a,auto b,auto c){
            LOG_ERROR<<"msgid:"<<msgid<<"can not find handler!";
        };
    }
    else
    {
        return _msgHandlerMap[msgid];
    }
    
}

//处理登录业务
void ChatService::login(const TcpConnectionPtr &conn,json &js,Timestamp)
{
    int id=js["id"].get<int>();
    string pwd=js["password"];

    User user=_userModel.query(id);
    if(user.getId()==id&&user.getPwd()==pwd){
        if(user.getState()=="online")
        {
            //该用户已经登录,不允许重复登录
            json response;
            response["msgid"]=LOGIN_MSG_ACK;
            response["errno"]=2;
            response["errmsg"]="该账号已经登录,请重新输入新账号";
            conn->send(response.dump());

        }else{
            //登录成功,更新用户状态信息 state offline=>online
            user.setState("online");
            _userModel.updateState(user);

            json response;
            response["msgid"]=LOGIN_MSG_ACK;
            response["errno"]=0;
            response["id"]=user.getId();
            response["name"]=user.getName();
            conn->send(response.dump());
        }
        
    }else{
        //该用户不存在,登录失败
        json response;
        response["msgid"]=LOGIN_MSG_ACK;
        response["errno"]=1;
        response["errmsg"]="用户名或者密码错误";
        conn->send(response.dump());
    }
}
//处理注册业务
void ChatService::reg(const TcpConnectionPtr &conn,json &js,Timestamp)
{
    string name=js["name"];
    string pwd=js["password"];

    User user;
    user.setName(name);
    user.setPwd(pwd);
    bool state=_userModel.insert(user);
    if(state)
    {
        //注册成功
        json response;
        response["msgid"]=REG_MSG_ACK;
        response["errno"]=0;
        response["id"]=user.getId();
        conn->send(response.dump());
    }else
    {
        //注册失败
        json response;
        response["msgid"]=REG_MSG_ACK;
        response["errno"]=1;
        conn->send(response.dump());
    }
}

数据模型层代码

//更新用户的状态信息
//根据用户号码查询用户信息
bool UserModel::updateState(User user)
{
    //组装sql语句
    char sql[1024]={0};
    sprintf(sql,"update user set state = '%s' where id=%d",user.getState().c_str(),user.getId());

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

}

但是问题就是,一登录成功就断开连接了

记录用户的连接信息以及线程安全问题

所以需要保存连接信息
在这里插入图片描述
在这里插入图片描述

这个表会被多线程访问,所以要考虑它的线程安全问题
上互斥锁!
C++STL里面并没有考虑线程安全问题
数据库的增删改查的并发操作是由MYSQL来保证的,不需要担心去上锁啥的。而线程安全需要保证
大括号表示作用域
在这里插入图片描述

客户端异常退出业务

在没有任何响应的情况下,连接突然断开了。比如网络连接问题
如果异常退出,并没有发送合法的json。用户状态如何?
在这里插入图片描述
这个业务完成两件事,一个是把存储用户通信连接的哈希表删除该用户的键值对2、将用户在数据库里的状态信息由online变成offline。
当出了大括号之后,锁就自动释放
在这里插入图片描述


http://www.kler.cn/a/402194.html

相关文章:

  • Linux进阶:压缩、解压
  • 高阶C语言之六:程序环境和预处理
  • 学习笔记022——Ubuntu 安装 MySQL8.0版本踩坑记录
  • 数造科技亮相第26届高交会并接受媒体采访,以数据智能赋能未来
  • freertos任务调度学习
  • IDEA2023 创建SpringBoot项目(一)
  • 游戏引擎学习第19天
  • 网络安全web之信息泄露
  • 语义分割(semantic segmentation)
  • 《生成式 AI》课程 第3講 CODE TASK执行文章摘要的机器人
  • 联通光猫(烽火通信设备)改桥接教程
  • 共建智能软件开发联合实验室,怿星科技助力东风柳汽加速智能化技术创新
  • 【学习心得】算力云平台上的大模型部署并实现远程调用
  • RabbitMQ消息可靠性保证机制4--消费端限流
  • EtherNet/IP从站转ModbusTCP主网关是一款 ETHERNET/IP 从站功能的通讯网关
  • python蓝桥杯刷题2
  • 【论文笔记】LoFLAT: Local Feature Matching using Focused Linear Attention Transformer
  • 基于AIRTEST和Jmeter、Postman的自动化测试框架
  • macbook外接2k/1080p显示器调试经验
  • linux 驱动之input子系统初探
  • unity 中 RectTransform 的常用几个属性
  • 一、Python基础语法(有C语言基础速成版)
  • 【linux】使用minicom调试串口
  • CH06_Lambda表达式
  • 【工具推荐】MobaXterm远程终端管理工具最全攻略,涉及下载、安装、字体配置、中文汉化版、中文显示乱码和中文输入乱码、adb tab无效无法补全、Telnet/ssh使用说明、使用技巧等保姆级教程
  • 驱动开发系列13 - Linux tasklet用法介绍