首页 > 编程语言 >C++项目——集群聊天服务器项目(七)Model层设计、注册业务实现

C++项目——集群聊天服务器项目(七)Model层设计、注册业务实现

时间:2024-03-29 21:59:36浏览次数:30  
标签:string 项目 用户 C++ name User Model id user

在前几节的研究中,我们已经实现网络层与业务层分离,本节实现数据层与业务层分离,降低各层之间的耦合性,同时实现用户注册业务。

网络层专注于处理网络通信与读写事件

业务层专注于处理读写事件到来时所需求的各项业务

数据层专注于与底层数据库间进行增删改查。

数据库中有User、Friend、AllGroup、GroupUser和OfflineMessage表,在model数据层中,要提供一些类与数据库中的表对应起来,以便于将数据库中读取到的字段信息也对象的方式提供给业务模块使用

项目流程如下:

1、项目环境搭建 

C++项目——集群聊天服务器项目(一)项目介绍、环境搭建、Boost库安装、Muduo库安装、Linux与vscode配置_c++集群聊天服务器-CSDN博客

2、Json第三方库介绍

C++项目——集群聊天服务器项目(二)Json第三方库-CSDN博客

3、muduo网络库介绍

C++项目——集群聊天服务器项目(三)muduo网络库-CSDN博客

4、MySQL数据库创建

C++项目——集群聊天服务器项目(四)MySQL数据库-CSDN博客

5、网络模块与业务模块代码编写

C++项目——集群聊天服务器项目(五)网络模块与业务模块-CSDN博客

6、MySQL模块编写

C++项目——集群聊天服务器项目(六)MySQL模块-CSDN博客

一、User类

在include/server下创建model文件夹,在model文件夹下创建与用户表对应的、操作用户的User类,定义在头文件user.hpp中,由于代码体量较小,直接在头文件中进行实现

用户表user

#ifndef USER_H
#define USER_H

#include <string>
using namespace std;

//User表的ORM类
class User
{
public:
    User(int id = -1, string name = "", string pwd = "", string state = "offline")
    {
        this->id = id;
        this->name = name;
        this->password = pwd;
        this->state = state;
    }
    
    //设置 
    void setId(int id) { this->id = id; }
    void setName(string name) { this->name = name; }
    void setPwd(string pwd) { this->password = pwd; }
    void setState(string state) { this->state = state; }
    
    //获取 
    int getId() { return this->id; }
    string getName() { return this->name; }
    string getPwd() { return this->password; }
    string getState() { return this->state; }

protected:
    int id;//ID号 
    string name;//姓名 
    string password;//密码 
    string state;//状态 
};

#endif

二、UserModel类

UserModel为操纵数据库User表的类,主要实现增加用户、查询用户、更新用户、重置用户信息

在include/server/model文件创建usermodel.hpp

#ifndef USERMODEL_H
#define USERMODEL_H

#include "user.hpp"

//User表的数据操作类
class UserModel {
public:
    //User表的增加方法
    bool insert(User &user);

    //根据用户号码查询用户信息
    User query(int id);

    //更新用户的状态信息
    bool updateState(User user);

    //重置用户的状态信息
    void resetState();
};

#endif

src/server中创建model文件夹,创建usermodel.cpp对UserModel类中insert方法进行实现

#include "usermodel.hpp"
#include "db.hpp"
#include <iostream>
using namespace std;

// User表的增加方法
bool UserModel::insert(User &user)
{
    // 1.组装sql语句
    char sql[1024] = {0};
    sprintf(sql, "insert into user(name, password, state) values('%s', '%s', '%s')",
            user.getName().c_str(), user.getPwd().c_str(), user.getState().c_str());

    MySQL mysql;         // 定义一个mysql对象
    if (mysql.connect()) // 连接成功了
    {
        if (mysql.update(sql)) // 更新这个sql语句传进去
        {
            // 获取插入成功的用户数据生成的主键id
            user.setId(mysql_insert_id(mysql.getConnection())); // 拿到数据库生成的id作为用户的id号
            return true;
        }
    }

    return false;
}

其余方法在实现后续功能模块中进行实现

三、注册功能

本节来实现注册功能,判断是否能通过UserModel类顺利将用户信息插入数据库中。

在public.hpp中定义注册消息和注册响应消息

#ifndef PUBLIC_H
#define PUBLIC_H

/*
server和client的公共文件
*/
enum EnMsgType
{
    LOGIN_MSG = 1, //登录消息
    REG_MSG, //注册消息 
    REG_MSG_ACK, //注册响应消息
};

#endif

注:此时登录消息对应的msgid=1,注册消息对应的msgid=2

在第五节C++项目——集群聊天服务器项目(五)网络模块与业务模块-CSDN博客中,注册与登录信息仅仅为一个日志信息,此处将注册业务进行实现

chatservice.hpp中,定义用户操作类对象

#ifndef CHATSERVICE_H
#define CHATSERVICE_H

#include <muduo/net/TcpConnection.h>
#include <unordered_map>//一个消息ID映射一个事件处理 
#include <functional>

using namespace std;
using namespace muduo;
using namespace muduo::net;

#include "usermodel.hpp"
#include "json.hpp"
using json = nlohmann::json;

//表示处理消息的事件回调方法类型,事件处理器,派发3个东西 
using MsgHandler = std::function<void(const TcpConnectionPtr &conn, json &js, Timestamp)>;

//聊天服务器业务类
class ChatService
{
public:
    //获取单例对象的接口函数
    static ChatService *instance();
    //处理登录业务
    void login(const TcpConnectionPtr &conn, json &js, Timestamp time);
    //处理注册业务
    void reg(const TcpConnectionPtr &conn, json &js, Timestamp time);

private:
    ChatService();//单例 

    //存储消息id和其对应的业务处理方法,消息处理器的一个表,写消息id对应的处理操作 
    unordered_map<int, MsgHandler> _msgHandlerMap;


    //数据操作类对象
    UserModel _userModel;


};

#endif

在chatservice.cpp中,编写注册业务函数

// 处理注册业务  name  password
void ChatService::reg(const TcpConnectionPtr &conn, json &js, Timestamp time)
{
    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()); // 回调 ,返回json字符串
    }
    else // 插入失败
    {
        // 注册失败
        json response;
        response["msgid"] = REG_MSG_ACK;
        response["errno"] = 1;
        conn->send(response.dump()); // 回调 ,返回json字符串
    }
}

步骤:

(1)从json对象中获取姓名和密码

(2)实例化User对象,分别将姓名和密码传入,使用UserModel类进行新用户的插入

注:状态默认为不在线(实际上创建的时候用户确实不在线),id由数据库派发

(3)定义json对象,回调响应信息,error = 0代表创建成功,error = 1代表创建失败。

若创建成功,需额外将创建成功的用户id号返回,如果失败,直接将json序列化发送回客户端

四、功能实现

使用CMake编译成功后,执行我们的ChatServer服务器,开启监听客户端连接

客户端使用下述命令登录服务器

telnet 127.0.0.1 6000

密码:123456

服务端显示有一个新的连接接入

客户端输入

{"msgid":2,"name":"Jiao","password":"123456"}

创建成功,返回error=0,用户id号以及注册响应msgid,如图所示

客户端,显示mysql连接成功了

我们进底层数据库看一下,

新建用户成功,功能实现完毕!(其他用户为自行学习时创建的)

感兴趣的小伙伴一起来试一下吧~

如果有问题还请及时联系我哦,感谢~

标签:string,项目,用户,C++,name,User,Model,id,user
From: https://blog.csdn.net/mingyuexin235/article/details/137155062

相关文章

  • 新写一个jsp项目之二:连接mysql数据库
    下载mysql-installer-community-5.7.44.0。jdbc驱动要是用8.3版本。mysql-connector-j-8.3.0参考菜鸟教程,将jdbc放入tomcat的lib文件夹。 写一个验证程序。 <%@pagelanguage="java"import="java.util.*,java.sql.DriverManager"pageEncoding="utf-8"%><%......
  • 大海捞针 Skia(C++) 第 4.1 期(特别篇):将绘制结果输出到窗口
    前言由于本人(我)没有系统学习过图形学,无法提供准确的术语表达,如果哪位大佬看到我的一些错误,还请友善指出!第四期之后,我一直纠结于应该讲些什么。图形学的东西我真的学的不多,未来也不是很想走这个方向。但是我仍然希望通过我的一些绵薄之力为一些苦苦寻找关于Skia资料的兄弟们提供......
  • 华为OD机试 - 传递悄悄话(Java & JS & Python & C & C++)
    须知哈喽,本题库完全免费,收费是为了防止被爬,大家订阅专栏后可以私信联系退款。感谢支持文章目录须知题目描述输入描述输出描述解题思路:题目描述给定一个二叉树,每个节点上站一个人,节点数字表示父节点到该节点传递悄悄话需要花费的时间。初始时,根节点所在......
  • 华为OD机试 - 剩余银饰的重量(Java & JS & Python & C & C++)
    须知哈喽,本题库完全免费,收费是为了防止被爬,大家订阅专栏后可以私信联系退款。感谢支持文章目录须知题目描述输入描述输出描述解题思路:题目描述有N块二手市场收集的银饰,每块银饰的重量都是正整数,收集到的银饰会被熔化用于打造新的饰品。每一回合,从中选......
  • 2024年03月CCF-GESP编程能力等级认证C++编程八级真题解析
    本文收录于专栏《C++等级认证CCF-GESP真题解析》,专栏总目录:点这里。订阅后可阅读专栏内所有文章。一、单选题(每题2分,共30分)第1题为丰富食堂菜谱,炒菜部进行头脑风暴。肉类有鸡肉、牛肉、羊肉、猪肉4种,切法有肉排、肉块、肉末3种,配菜有圆白菜、油菜、豆腐3种,辣度有......
  • 2024年03月CCF-GESP编程能力等级认证C++编程七级真题解析
    本文收录于专栏《C++等级认证CCF-GESP真题解析》,专栏总目录:点这里。订阅后可阅读专栏内所有文章。一、单选题(每题2分,共30分)第1题下列关于排序的说法,正确的是()。A.冒泡排序是最快的排序算法之一。B.快速排序通常是不稳定的。C.最差情况,N个元素做归并排序......
  • 追光几何Lite用户分享之项目管理
    在我作为项目管理人员的职业生涯中,面对众多跨领域的项目,我不断地寻找高效的方法和工具来优化项目文件的管理。在众多尝试中,我发现了追光几何Lite,一款简洁实用的本地文件版本管理软件,它极大地提升了我的工作效率和文件管理的质量。项目管理过程中会产生众多文件和文档,从项目计......
  • ccfcsp-2019-12-2回收站选址(c++满分题解)
    该题就是考察点的保存以及索引的保存和遍历,看了他的用例说明,我原先以为暴力只能得50分,但是又没有想到别的优化方法,就写了一下暴力,发现居然AC下面是代码:#include<iostream>#include<vector>#include<map>usingnamespacestd;intmain(){ intn; cin>>n; vector<pair<......
  • IDEA 上传 git 项目
     1.创建项目:菜单栏找到VCS,创建git仓库,此时代码变红了 2.右击项目找到GIT-->Add,代码绿了 3.存于本地:右击项目 找到Git--> CommitDirectory... 4.此时存在本地git,编辑后点击Commit出错了,不重要。 commit后代码白了。 5.拉取代码,右击项目 ......
  • SpringBoot项目接入Nacos的实现步骤
    前言项目中没有使用nacos官方提供的方式使用SpringBoot的集成方式来进行集成,而是使用了AlibabaSpringCloud的依赖包进行集成。原因是因为官网提供的SpringBoot集成方式中,同时使用配置中心和服务发现功能,会使得服务发现功能配置的部分属性冲突不生效。最直接的就是配置中心和服......