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连接成功了
我们进底层数据库看一下,
新建用户成功,功能实现完毕!(其他用户为自行学习时创建的)
感兴趣的小伙伴一起来试一下吧~
如果有问题还请及时联系我哦,感谢~
相关文章:
C++项目——集群聊天服务器项目(七)Model层设计、注册业务实现
在前几节的研究中,我们已经实现网络层与业务层分离,本节实现数据层与业务层分离,降低各层之间的耦合性,同时实现用户注册业务。 网络层专注于处理网络通信与读写事件 业务层专注于处理读写事件到来时所需求的各项业务 数据层专…...
VBA语言専攻介绍(20240331更新)
VBA语言専攻简介 “VBA语言専攻”是大家汲取知识的源泉,是提高自己能力的净土,正如我对平台的介绍:社会的进步,源于对知识的尊重和敬仰。希望每一位学员,每一位关注平台的朋友,都能很好的利用这个平台来学…...
Golang- 邮件服务,发送邮件
依赖 go get -u github.com/jordan-wright/email文档 文档 示例代码 邮箱的相关配置 # email configuration email:port: 25 # 端口要配置25 否则可能出现EOF错误from: xxx1qq.comhost: smtp.qq.comis-ssl: truesecret: xxxxxnickname: 大锦余发送邮件代码 package utili…...
C语言:编译和链接
前言 在ANSI C的任何一种实现中,存在两个不同的环境。 第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令(二进制指令)。第2种是执行环境,它用于实际执行代码。 目录 1.翻译环境1.1 预处理(预编…...
JavaEE 初阶篇-深入了解多线程安全问题(出现线程不安全的原因与解决线程不安全的方法)
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 多线程安全问题概述 1.1 线程不安全的实际例子 2.0 出现线程不安全的原因 2.1 线程在系统中是随机调度且抢占式执行的模式 2.2 多个线程同时修改同一个变量 2.3 线…...
计算机网络⑦ —— 网络层协议
1. ARP协议 在传输⼀个 IP 数据报的时候,确定了源 IP 地址和⽬标 IP 地址后,就会通过主机路由表确定 IP 数据包下⼀跳。然⽽,⽹络层的下⼀层是数据链路层,所以我们还要知道下⼀跳的 MAC 地址。由于主机的路由表中可以找到下⼀跳的…...
正弦实时数据库(SinRTDB)的使用(7)-历史统计查询
前文已经将正弦实时数据库的使用进行了介绍,需要了解的可以先看下面的博客: 正弦实时数据库(SinRTDB)的安装 正弦实时数据库(SinRTDB)的使用(1)-使用数据发生器写入数据 正弦实时数据库(SinRTDB)的使用(2)-接入OPC DA的数据 正弦实时数据库(SinRTDB)…...
编译和链接知识点
为什么我们在vs等编译器上写出的代码通过运行就会实现相关功能呢? 解决这个问题的关键就是关于编译与链接的知识。 首先从大的分类里有两部分:编译和链接 而编译这一大的部分又分为预处理(也叫预编译),编译…...
大话设计模式之工厂模式
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的最佳方式,而无需指定将要创建的对象的确切类。通过使用工厂模式,我们可以将对象的创建和使用分离,从而使代码更具灵活性和可维护性。…...
Windows MySQL通过data 文件夹恢复数据
前言 在MySql数据库中,为了备份和恢复数据,通常会使用mysqldump工具来导出和导入数据。但是,如果数据库非常大,name导出和导入数据可能会需要很长时间。这时,一种更快速的备份和恢复数据的方式就是直接复制mysql的data文件夹。 什么是mysql的…...
ARP协议定义及工作原理
ARP的定义 地址解析协议(Address Resolution Protocol,ARP):ARP协议可以将IPv4地址(一种逻辑地址)转换为各种网络所需的硬件地址(一种物理地址)。换句话说,所谓的地址解析的目标就是发现逻辑地址与物理地址的映射关系。 ARP仅用于IPv4协议&a…...
express实现用户登录和注册接口
目录 1 创建数据库2 连接数据库3 集成ORM库4 创建业务逻辑5 创建路由7 测试接口总结 我们在编写后端接口的时候操作数据库是一种常见的功能需求,express本身并不提供直接操作数据库的能力,需要借助第三方库来操作数据库,本篇讲解一下软件开发…...
数字化转型,效率增长才是王道
在当今商业世界,数字化已经成为推动企业增长的强大引擎。然而,值得注意的是,数字化并非只是简单地追求规模扩张,更重要的是实现降本增效。没有效率的增长,就像是在加速自我毁灭。在数字化转型的道路上,企业…...
RHCE-2-chrony服务器
简介 重要性 由于IT系统中,准确的计时非常重要,有很多种原因需要准确计时: 在网络传输中,数据包括和日志需要准确的时间戳 各种应用程序中,如订单信息,交易信息等 都需要准确的时间戳 Linux的两个时钟 硬…...
音频RK809
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、目的二、知识准备2.1Audio框架2.1.1 DAI2.1.2 CODEC2.1.3 machine三、原理图3.1 整体原理图3.2 喇叭部分3.3 麦克风部分四、设备树4.1 sound 部分4.2 codec 部分五、驱动讲...
解决 linux 服务器 java 命令不生效问题
在Linux系统中,当你安装Java并设置了JAVA_HOME环境变量后,你可能需要使用source /etc/profile命令来使Java命令生效。这是因为/etc/profile是一个系统级的配置文件,它包含了系统的全局环境变量设置。 但是需要注意的是,source /e…...
22 多态
目录 多态的概念多态的定义及实现抽象类多态的原理单继承和多继承关系中的虚函数表继承和多态常见的面试问题 前言 需要声明的,下面的代码和解释的哦朴实vs2013x86环境,涉及指针是4bytes,如果要其他平台下,部分代码需要改动。比…...
排序算法超详细代码和知识点整理(java版)
排序 1、冒泡排序 两层循环,相邻两个进行比较,大的推到后面去,一共比较“数组长度”轮,每一轮都是从第一个元素开始比较,每一轮比较都会将一个元素固定到数组最后的一个位置。【其实就是不停的把元素往后堆&#…...
Java复习第十二天学习笔记(JDBC),附有道云笔记链接
【有道云笔记】十二 3.28 JDBC https://note.youdao.com/s/HsgmqRMw 一、JDBC简介 面向接口编程 在JDBC里面Java这个公司只是提供了一套接口Connection、Statement、ResultSet,每个数据库厂商实现了这套接口,例如MySql公司实现了:MySql驱动…...
Python从零到一构建GPT模型
只用Python和 torch框架,从零到一构建GPT模型,对大语言模型入门,了解GPT的内部网络结构,是一个很好示例。 Build_GPT_from_Scratch.ipynb...
V R虚拟现实元宇宙的前景|虚拟现实体验店加 盟合作|V R设备在线购买
VR(虚拟现实)技术作为一种新兴的技术,正在逐渐改变人们的生活和工作方式。随着技术的不断进步,人们对于元宇宙的概念也越来越感兴趣。元宇宙是一个虚拟世界,通过VR技术可以实现人们在其中进行各种活动和交互。 元宇宙的…...
大话设计模式之策略模式
策略模式是一种行为设计模式,它允许在运行时选择算法的行为。这种模式定义了一族算法,将每个算法都封装起来,并且使它们之间可以互相替换。 在策略模式中,一个类的行为或其算法可以在运行时改变。这种模式包含以下角色࿱…...
蓝桥杯23年第十四届省赛真题-三国游戏|贪心,sort函数排序
题目链接: 1.三国游戏 - 蓝桥云课 (lanqiao.cn) 蓝桥杯2023年第十四届省赛真题-三国游戏 - C语言网 (dotcpp.com) 虽然这道题不难,很容易想到,但是这个视频的思路理得很清楚: [蓝桥杯]真题讲解:三国游戏࿰…...
P15:PATH环境变量
为什么要配置环境变量 当我们打开DOS窗口,输入:javac,出现下面问题。 原因:windows操作系统在当前目录中无法找到javac命令文件。Windows操作系统是如何搜索硬盘上某一个命令? 首先从当前目录中搜索该命令如果当前目录…...
math模块篇(七)
文章目录 math.dist(p, q)math.hypot(*coordinates)math.sin(x)math.tan(x)math.degrees(x)math.radians(x)math.acosh(x)math.asinh(x)math.atanh(x) math.dist(p, q) 在Python的math模块中,并没有一个名为math.dist(p, q)的函数。可能你是想要计算两点p和q之间的…...
wordpress插件,免费的wordpress插件
WordPress作为世界上最受欢迎的内容管理系统之一,拥有庞大的插件生态系统,为用户提供了丰富的功能扩展。在内容创作和SEO优化方面,有一类特殊的插件是自动生成原创文章并自动发布到WordPress站点的工具。这些插件能够帮助用户节省时间和精力&…...
Remote Desktop Manager for Mac:远程桌面管理软件
Remote Desktop Manager for Mac,是远程桌面管理的理想之选。它集成了多种远程连接技术,无论是SSH、RDP还是VNC,都能轻松应对,让您随时随地安全访问远程服务器和工作站。 软件下载:Remote Desktop Manager for Mac下载…...
如何撰写研究论文
SEVENTYFOUR/SHUTTERSTOCK 即使对于有经验的作家来说,将数月或数年的研究浓缩到几页纸中也是一项艰巨的任务。作者需要在令人信服地解决他们的科学问题和详细地呈现他们的结果之间找到最佳平衡点,以至于丢失了关键信息。他们必须简明扼要地描述他们的方…...
数据结构
一、栈 先进后出 二、队列 先进先出 三、数组 查询快,增加修改慢 四、链表 查询慢,增加修改慢 五、二叉树 节点: 查找二叉树 二叉查找树的特点 二叉查找树,又称二叉排序树或者二叉搜索树 每一个节点上最多有两个子节点 左子树上所…...
动态规划相关题目
文章目录 1.动态规划理论基础2.斐波那契数3.爬楼梯4.使用最小花费爬楼梯5.不同路径6.不同路径 II7. 整数拆分8. 不同的二叉搜索树 1.动态规划理论基础 1.1 什么是动态规划? 动态规划,英文:Dynamic Programming,简称DP,如果某一…...
网站推广的10种方法/旅游营销推广方案
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Sprin…...
网站怎么申请支付宝/360营销平台
今天考完软考的网络工程师了,考的挺好的。心里没多大的感想,毕竟一直在学习,刚好最近一直在做ipsec 的实验,然后最后一题就考了。看到试题,心里的感想挺多的。人与人之间是不能架起的。事情走到今天,也已经…...
wordpress iframe页面/35个成功的市场营销策划案例
http://www.cnblogs.com/wservices/archive/2010/07/08/1773449.html 看到很多书中都没有对PreferenceActivity做介绍,而我正好又在项目中用到,所以就把自己的使用的在这总结一下,也方便日后查找。 PerferenceActivity是什么,看下…...
口碑好的网站建设平台/小红书sem是什么意思
一、过滤器的作用 过滤器用来格式化须要展示给用户的数据。 在HTML中的模板绑定符号{{ }}内通过|符号来调用过滤器。比如。如果我们希望将字符串转换成大写能够对字符串中的每一个字符都单独进行转换操作。也能够使用过滤器:{{name | uppercase }} ◇给过滤器传參数…...
做网上卖酒的网站有几家/seo模拟点击
H参数表示色彩信息,即所处的光谱颜色的位置。该参数用一角度量来表示,红、绿、蓝分别相隔120度。互补色分别相差180度。纯度S为一比例值,范围从0到1,它表示成所选颜色的纯度和该颜色最大的纯度之间的比率。S0时,只有灰…...
百度快照 直接进网站/google移动服务应用优化
监控系统进程资源的使用情况是IT运维的常规操作。在实际工作中,运维人员有可能遇到可以使用Zabbix Agent监控linux系统进程,却无法监控windows系统进程的情况。这是因为Zabbix Agent可以通过linux系统内置键值进行监控进程,而windows平台则不…...