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

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层设计、注册业务实现

在前几节的研究中&#xff0c;我们已经实现网络层与业务层分离&#xff0c;本节实现数据层与业务层分离&#xff0c;降低各层之间的耦合性&#xff0c;同时实现用户注册业务。 网络层专注于处理网络通信与读写事件 业务层专注于处理读写事件到来时所需求的各项业务 数据层专…...

VBA语言専攻介绍(20240331更新)

VBA语言専攻简介 “VBA语言専攻”是大家汲取知识的源泉&#xff0c;是提高自己能力的净土&#xff0c;正如我对平台的介绍&#xff1a;社会的进步&#xff0c;源于对知识的尊重和敬仰。希望每一位学员&#xff0c;每一位关注平台的朋友&#xff0c;都能很好的利用这个平台来学…...

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的任何一种实现中&#xff0c;存在两个不同的环境。 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令&#xff08;二进制指令&#xff09;。第2种是执行环境&#xff0c;它用于实际执行代码。 目录 1.翻译环境1.1 预处理&#xff08;预编…...

JavaEE 初阶篇-深入了解多线程安全问题(出现线程不安全的原因与解决线程不安全的方法)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 多线程安全问题概述 1.1 线程不安全的实际例子 2.0 出现线程不安全的原因 2.1 线程在系统中是随机调度且抢占式执行的模式 2.2 多个线程同时修改同一个变量 2.3 线…...

计算机网络⑦ —— 网络层协议

1. ARP协议 在传输⼀个 IP 数据报的时候&#xff0c;确定了源 IP 地址和⽬标 IP 地址后&#xff0c;就会通过主机路由表确定 IP 数据包下⼀跳。然⽽&#xff0c;⽹络层的下⼀层是数据链路层&#xff0c;所以我们还要知道下⼀跳的 MAC 地址。由于主机的路由表中可以找到下⼀跳的…...

正弦实时数据库(SinRTDB)的使用(7)-历史统计查询

前文已经将正弦实时数据库的使用进行了介绍&#xff0c;需要了解的可以先看下面的博客&#xff1a; 正弦实时数据库(SinRTDB)的安装 正弦实时数据库(SinRTDB)的使用(1)-使用数据发生器写入数据 正弦实时数据库(SinRTDB)的使用(2)-接入OPC DA的数据 正弦实时数据库(SinRTDB)…...

编译和链接知识点

为什么我们在vs等编译器上写出的代码通过运行就会实现相关功能呢&#xff1f; 解决这个问题的关键就是关于编译与链接的知识。 首先从大的分类里有两部分&#xff1a;编译和链接 而编译这一大的部分又分为预处理&#xff08;也叫预编译&#xff09;&#xff0c;编译&#xf…...

大话设计模式之工厂模式

工厂模式&#xff08;Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一种创建对象的最佳方式&#xff0c;而无需指定将要创建的对象的确切类。通过使用工厂模式&#xff0c;我们可以将对象的创建和使用分离&#xff0c;从而使代码更具灵活性和可维护性。…...

Windows MySQL通过data 文件夹恢复数据

前言 在MySql数据库中,为了备份和恢复数据,通常会使用mysqldump工具来导出和导入数据。但是&#xff0c;如果数据库非常大&#xff0c;name导出和导入数据可能会需要很长时间。这时&#xff0c;一种更快速的备份和恢复数据的方式就是直接复制mysql的data文件夹。 什么是mysql的…...

ARP协议定义及工作原理

ARP的定义 地址解析协议(Address Resolution Protocol&#xff0c;ARP)&#xff1a;ARP协议可以将IPv4地址(一种逻辑地址)转换为各种网络所需的硬件地址(一种物理地址)。换句话说&#xff0c;所谓的地址解析的目标就是发现逻辑地址与物理地址的映射关系。 ARP仅用于IPv4协议&a…...

express实现用户登录和注册接口

目录 1 创建数据库2 连接数据库3 集成ORM库4 创建业务逻辑5 创建路由7 测试接口总结 我们在编写后端接口的时候操作数据库是一种常见的功能需求&#xff0c;express本身并不提供直接操作数据库的能力&#xff0c;需要借助第三方库来操作数据库&#xff0c;本篇讲解一下软件开发…...

数字化转型,效率增长才是王道

在当今商业世界&#xff0c;数字化已经成为推动企业增长的强大引擎。然而&#xff0c;值得注意的是&#xff0c;数字化并非只是简单地追求规模扩张&#xff0c;更重要的是实现降本增效。没有效率的增长&#xff0c;就像是在加速自我毁灭。在数字化转型的道路上&#xff0c;企业…...

RHCE-2-chrony服务器

简介 重要性 由于IT系统中&#xff0c;准确的计时非常重要&#xff0c;有很多种原因需要准确计时&#xff1a; 在网络传输中&#xff0c;数据包括和日志需要准确的时间戳 各种应用程序中&#xff0c;如订单信息&#xff0c;交易信息等 都需要准确的时间戳 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系统中&#xff0c;当你安装Java并设置了JAVA_HOME环境变量后&#xff0c;你可能需要使用source /etc/profile命令来使Java命令生效。这是因为/etc/profile是一个系统级的配置文件&#xff0c;它包含了系统的全局环境变量设置。 但是需要注意的是&#xff0c;source /e…...

22 多态

目录 多态的概念多态的定义及实现抽象类多态的原理单继承和多继承关系中的虚函数表继承和多态常见的面试问题 前言 需要声明的&#xff0c;下面的代码和解释的哦朴实vs2013x86环境&#xff0c;涉及指针是4bytes&#xff0c;如果要其他平台下&#xff0c;部分代码需要改动。比…...

排序算法超详细代码和知识点整理(java版)

排序 1、冒泡排序 ​ 两层循环&#xff0c;相邻两个进行比较&#xff0c;大的推到后面去&#xff0c;一共比较“数组长度”轮&#xff0c;每一轮都是从第一个元素开始比较&#xff0c;每一轮比较都会将一个元素固定到数组最后的一个位置。【其实就是不停的把元素往后堆&#…...

Java复习第十二天学习笔记(JDBC),附有道云笔记链接

【有道云笔记】十二 3.28 JDBC https://note.youdao.com/s/HsgmqRMw 一、JDBC简介 面向接口编程 在JDBC里面Java这个公司只是提供了一套接口Connection、Statement、ResultSet&#xff0c;每个数据库厂商实现了这套接口&#xff0c;例如MySql公司实现了&#xff1a;MySql驱动…...

Python从零到一构建GPT模型

只用Python和 torch框架&#xff0c;从零到一构建GPT模型&#xff0c;对大语言模型入门&#xff0c;了解GPT的内部网络结构&#xff0c;是一个很好示例。 Build_GPT_from_Scratch.ipynb...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...