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

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

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

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

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

数据库中有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语句传进去{// 获取插入成功的用户数据生成的主键iduser.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连接成功了

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/786772.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UE5 SQLite笔记

开发环境&#xff1a; 系统&#xff1a;Windows 10 64 bit 引擎&#xff1a;Unreal Engine 5.1.1 IDE&#xff1a;JetBrains Rider 2023.2.1 语言&#xff1a;C 工具&#xff1a;DB Browser for SQLite SQLite数据类型&#xff1a; //INTEGER TEXT BLOB REAL NUMERIC/*integer…

关于OpenFeign的返回类型包装问题

在一天夜里。我在使用feign的调用时&#xff0c;突然出现了一点点问题。 就是对于feign类型的包装问题。产生了疑问。 在后来&#xff0c;也就是今天。在网上取取经。看到了一个答案。说&#xff1a;feign的调用会有一个编码器和解码器。 使用feign的解码器。他的原理也很简…

NoSQL之Redis配置

文章目录 NoSQL之Redis配置一、关系数据库和非关系数据库1、关系型数据库2、非关系型数据库3、非关系型数据库产生背景4、关系型数据库和非关系型数据库的区别4.1 数据存储方式不同4.2 扩展方式不同4.3 对事务性的支持不同 5、总结5.1 关系型数据库5.2 非关系型数据库 二、Redi…

基于springboot实现房屋租赁管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现房屋租赁系统演示 摘要 房屋是人类生活栖息的重要场所&#xff0c;随着城市中的流动人口的增多&#xff0c;人们对房屋租赁需求越来越高&#xff0c;为满足用户查询房屋、预约看房、房屋租赁的需求&#xff0c;特开发了本基于Spring Boot的房屋租赁系统。 …

鸿蒙实战开发-如何使用三方库

使用三方库 在使用三方库之前&#xff0c;需要安装 ohpm&#xff0c;并在环境变量中配置。 在项目目录的Terminal窗口执行ohpm命令下载依赖 ohpm install yunkss/eftool 命令运行成功后&#xff0c;在项目的oh-package.json5文件中会自动添加上依赖&#xff0c;如下所示&am…

JimuReport积木报表 v1.7.4 正式版本发布,免费的JAVA报表工具

项目介绍 一款免费的数据可视化报表&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于excel操作风格&#xff0c;通过拖拽完成报…

Qt加载.css/.qss文件设置控件的QSS样式(支持程序运行时修改且立即生效类似换肤效果)

初学Qt时&#xff0c;你是如何设置QWidget&#xff0c;QPushButton等原生基础控件的样式的&#xff1f;是不是主要是两种方法&#xff1f; 1.直接在可视化的.ui文件中直接添加qss语句。 2.在代码中通过setStyleSheet(QString qss)来设置qss语句。 上述两种方法&#xff0c;在程…

【数据结构】你知道波兰表达式和逆波兰表达式吗?我才知道原来栈在表达式求值中还能这样使用……

栈在表达式求值中的应用 导读一、表达式的形式二、波兰表达式与逆波兰表达式三、表达式之间的相互转换四、栈实现波兰表达式4.1 问题分析4.2 问题完善4.3 算法实现4.3.1 获取波兰表达式4.3.2 从右往左扫描表达式4.3.3 遇到操作数进行入栈操作4.3.4 遇到操作符进行对应操作4.3.5…

Qt元对象系统

第二章Qt元对象系统 文章目录 第二章Qt元对象系统1.什么是元对象&#xff1f;2.元对象系统组成3.信号与槽信号和槽的本质绑定信号与槽自定义槽定义槽函数必须遵循一下规则槽函数的类型自定义槽案例 自定义信号自定义信号需要遵循以下规则信号和槽重载二义性问题 4.内存管理1. 简…

原生小程序开发性能优化指南

性能优化指南 1.骨架屏 业务可以在数据加载完成之前用骨架屏幕来占位&#xff0c;提升体验。 2.包大小优化 减小包中静态资源&#xff0c;例如图片文件&#xff0c;可将图片进行压缩降低文件体积。无用文件、函数、样式剔除。除了部分用于容错的图片必须放在代码包&#xf…

了解游戏相关知识

个人笔记&#xff08;整理不易&#xff0c;有帮助点个赞&#xff09; 笔记目录&#xff1a;学习笔记目录_pytest和unittest、airtest_weixin_42717928的博客-CSDN博客 个人随笔&#xff1a;工作总结随笔_8、以前工作中都接触过哪些类型的测试文档-CSDN博客 目录 一&#xff1a…

MySQL常见故障案例与优化介绍

前言 MySQL故障排查的意义在于及时识别并解决数据库系统中的问题&#xff0c;确保数据的完整性和可靠性&#xff1b;而性能优化则旨在提高数据库系统的效率和响应速度&#xff0c;从而提升用户体验和系统整体性能。这两方面的工作都对于保证数据库系统稳定运行、提升业务效率和…

加域报错:找不到网络路径

在尝试将计算机加入Windows域时&#xff0c;如果收到“找不到网络路径”的错误提示&#xff0c;可能的原因及解决方法如下&#xff1a; 网络连接问题&#xff1a;确保计算机与域控制器之间的物理网络连接是正常的&#xff0c;可以通过ping命令测试与域控制器的连通性。例如&…

LeetCode 56. 合并区间

以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;intervals [[1,3…

HarmonyOS 应用开发之LifecycleService接口切换LifecycleData接口切换

LifecycleService接口切换 FA模型接口Stage模型接口对应d.ts文件Stage模型对应接口onStart?(): void;ohos.app.ability.ServiceExtensionAbility.d.tsonCreate(want: Want): void;onCommand?(want: Want, startId: number): void;ohos.app.ability.ServiceExtensionAbility.…

c# 插值搜索-迭代与递归(Interpolation Search)

给定一个由 n 个均匀分布值 arr[] 组成的排序数组&#xff0c;编写一个函数来搜索数组中的特定元素 x。 线性搜索需要 O(n) 时间找到元素&#xff0c;跳转搜索需要 O(? n) 时间&#xff0c;二分搜索需要 O(log n) 时间。 插值搜索是对实例二分搜索的改进&#xff0c;…

前端 - 基础 表单标签 - 表单元素 input - (name Value checked maxlength )属性详解

目录 name 属性 Value 属性 Checked 属性 Maxlength 属性 场景问答 # <input> 标签 除了 type 属性外&#xff0c;还有其他常用属性 >>> name 属性 在上一节 我们遇到的 单选按钮 &#xff0c;为什么 本应该 多选一 结果成了 多选多的问题 就…

# 达梦数据库知识点

达梦数据库知识点 测试数据 -- SYSDBA.TABLE_CLASS_TEST definitionCREATE TABLE SYSDBA.TABLE_CLASS_TEST (ID VARCHAR(100) NOT NULL,NAME VARCHAR(100) NULL,CODE VARCHAR(100) NULL,TITLE VARCHAR(100) NULL,CREATETIME TIMESTAMP NULL,COLUMN1 VARCHAR(100) NULL,COLUMN…

利用甘特图实现精细化项目管控

在项目管理中,通过精细化管控,项目经理能够有效规划、监督和协调各项任务,从而最大限度控制风险,优化资源配置,并确保按时、按质、按量完成项目目标。而在众多项目管理工具中,甘特图无疑是实现精细化项目管控的利器。zz-plan 是一个非常好用的在线甘特图制作工具&#xff0c;一…

Day78:服务攻防-数据库安全RedisCouchDBH2database未授权访问CVE漏洞

目录 前置知识 数据库应用-Redis-未授权访问&CVE漏洞 未授权访问&#xff1a;CNVD-2015-07557 未授权访问-CNVD-2019-21763 未授权访问-沙箱绕过RCE-CVE-2022-0543 数据库应用-Couchdb-未授权越权&CVE漏洞 Couchdb 垂直权限绕过&#xff08;CVE-2017-12635&…