【Qt】前后端交互---DataCenter类

news2024/9/27 10:54:24

设计目的

前后端交互系统中,创建并使用数据核心类的目的就是让该类作为客户端的数据中心,也就是说其负责管理客户端的所有数据与服务器的网络通信。

数据持久化

初始化数据文件

该函数设计的目的就是用于检查所需要的文件和目录是否存在,如果不存在创建,确保客户端和服务端的数据都是存储在同一位置上的。

void DataCenter::initDataFile()
{
    QString basePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
    QString filePath = basePath + "/ChatClient.json";

    QDir dir;
    if (!dir.exists(basePath)) {
        dir.mkpath(basePath);
    }

    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        LOG() << "打开文件失败!" << file.errorString();
        return;
    }
    QString data = "{\n\n}";
    file.write(data.toUtf8());
    file.close();
}

 加载数据文件

也就是从本地JSON文件中读取数据,将其解析为可用的对象,然后填充到内存中的数据结构中。

void DataCenter::loadDataFile()
{
    QString filePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/ChatClient.json";
    QFileInfo fileInfo(filePath);
    if (!fileInfo.exists()) {
        initDataFile();
    }

    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        LOG() << "打开文件失败!" << file.errorString();
        return;
    }

    QJsonDocument jsonDoc = QJsonDocument::fromJson(file.readAll());
    if (jsonDoc.isNull()) {
        LOG() << "解析JSON文件失败! JSON文件格式错误";
        file.close();
        return;
    }

    QJsonObject jsonObj = jsonDoc.object();
    this->loginSessionId = jsonObj["loginSessionId"].toString();

    this->unreadMessageCount->clear();
    QJsonObject jsonUnread = jsonObj["unread"].toObject();
    for (auto it = jsonUnread.begin(); it != jsonUnread.end(); ++it) {
        this->unreadMessageCount->insert(it.key(), it.value().toInt());
    }
    file.close();
}

保存数据文件 

设计该方法的目的就是将当前的数据状态写回到JSON文件,从而确保数据在应用程序重启后依然可以使用。

void DataCenter::saveDataFile()
{
    QString filePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/ChatClient.json";

    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        LOG() << "文件打开失败" << file.errorString();
        return;
    }

    QJsonObject jsonObj;
    jsonObj["loginSessionId"] = loginSessionId;

    QJsonObject jsonUnread;
    for (auto it = unreadMessageCount->begin(); it != unreadMessageCount->end(); ++it) {
        jsonUnread[it.key()] = it.value();
    }
    jsonObj["unread"] = jsonUnread;

    QJsonDocument jsonDoc(jsonObj);
    QString s = jsonDoc.toJson();
    file.write(s.toUtf8());

    file.close();
}

内存数据管理

 用户信息管理

维护当前登录用户的信息,也就是用来保存当前登录用户的信息、好友列表等相关信息

UserInfo *DataCenter::getMyself()
{
    return myself;
}

void DataCenter::resetMyself(std::shared_ptr<bite_im::GetUserInfoRsp> resp)
{
    if (myself == nullptr) {
        myself = new UserInfo();
    }
    const bite_im::UserInfo &userInfo = resp->userInfo();
    myself->load(userInfo);
}

消息管理 

负责管理最近的消息,聊天会话记录、未读信息等相关消息

// 在构造函数中初始化未读消息计数哈希表
DataCenter::DataCenter() : netClient(this)
{
    unreadMessageCount = new QHash<QString, int>();
    // 其他初始化操作
}

前后端通信

 异步数据获取

通过netClient对象与服务器通信,使用异步方法来获取数据,避免阻塞线程,从而确保UI响应

void DataCenter::getMyselfAsync()
{
    netClient.getMyself(loginSessionId);
}

数据同步 

服务器接收到数据后,需要更新本地的数据

void DataCenter::resetMyself(std::shared_ptr<bite_im::GetUserInfoRsp> resp)
{
    if (myself == nullptr) {
        myself = new UserInfo();
    }
    const bite_im::UserInfo &userInfo = resp->userInfo();
    myself->load(userInfo);
}

数据核心类与其他类的联系

前后端交互数据存储在DataCenter

数据核心类的作用就是在客户端应用程序中集中管理和存储与前后端交互的相关数据。其是作为数据核心类存在的。 

  • 统一存储应用中所需要的数据,例如用户信息、好友列表、消息记录等,都集中存储在一个地方,方便访问和管理
  • 通过集中管理保证数据一致性,避免不同模块之间的数据不一致的情况
  • 数据共享,通过将需要使用的数据都存放在一个类中,从而供其他的对象对其数据进行调用

DataCenter和MainWindow类的关系

首先MainWindow就是应用程序的主界面,DataCenter是数据管理类,专门负责处理数据的存取与服务器通信。所以两者之间主要存在两种关系。

  • MainWindow是依赖于DataCenter。因为主窗口需要从数据核心类中获取数据显示,就必须显示个人信息,就需要通过数据核心类来获取
  • DataCenter独立于MainWindow。数据核心类是不与界面直接进行交互的,而是专门负责数据处理和存储。

其次从实例对应关系上分析,也就是从数据核心类实例后对象与其他部分的关系分析

  • DataCenter类设计成单例模式,保证整个应用程序中只有一个DataCenter实例,这也是为了确保数据的一致性和共享性
  • 用户级别考虑,因为一个数据核心类中肯定是只可以存储一个用户的数据和信息,也就是说每个用户都会有自己的数据核心类和主窗口实例
  • 用户切换情况下,如果支持多用户的客户端应用程序,那么在多用户切换的情况下,需要清空核心数据类中存储的信息,然后重新加载新的数据

前后端交互过程中Qt应用层和原理层

应用层面 

  • 异步通信机制:客户端发送请求后到服务器后,通常是不会阻塞等待服务器响应的,而是通过异步机制等待结果,所以应用层使用的是异步机制
  • 信号与槽机制:当服务器处理完成请求后并返回结果后,客户端的网络模块会发送一个信号,通知应用程序已经准备好
  • 处理响应:应用程序中预先连接了对应的槽函数,也就是在信号发出后,槽函数就会被调用,进行数据处理和更新页面

原理层面

  • 事件驱动:服务器的运行逻辑是依靠事件驱动模型实现的,也就是当有事件的时候,事件循环会触发相应的处理函数
  • 异步I/O:Qt的网络模块内部使用的是异步IO,当数据到达后,会自动触发信号,但是不会造成线程阻塞
  • 线程安全:信号和槽是可以跨线程工作的,确保不同线程下传递数据的安全性

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

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

相关文章

【C/C++】【基础数论】33、算数基本定理

算术基本定理&#xff0c;又称正整数的唯一分解定理。 说起来比较复杂&#xff0c;但是看一下案例就非常清楚了 任何一个大于 1 的正整数都可以唯一地分解成有限个质数的乘积形式&#xff0c;且这些质数按照从小到大的顺序排列&#xff0c;其指数也是唯一确定的。 例如&#…

mvnd 初体验

https://github.com/apache/maven-mvnd/releases?page2 mvnd内嵌了Maven&#xff08;因此不需要单独安装Maven&#xff09;。mvnd客户端是通过GraalVM构建的可执行文件&#xff0c;与启动传统JVM相比&#xff0c;它的启动速度更快&#xff0c;占用的内存更少。实际构建发生在一…

【Python报错已解决】TypeError: list indices must be integers or slices, not str

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

2.归并排序算法【分治】

步骤&#xff1a; 确定分界点&#xff0c;mid (lr)/2递归排序left、right归并&#xff0c;合二为一 package base;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;public class Merge_sort {static int n;static int q[];s…

TinyWebSever项目面试题整理

TinyWebSever项目面试题整理 1.为什么要做这样一个项目&#xff1f; 满足高并发和高性能需求&#xff1a;现代Web应用面对大量用户&#xff0c;Web服务器需要高效处理并发连接。比如通过线程池、非阻塞I/O、事件驱动机制&#xff08;如epoll&#xff09;&#xff0c;Web服务器…

【深度学习】(9)--调整学习率

文章目录 调整学习率一、学习率的定义二、学习率的作用三、实现调整学习率1. 使用库函数进行调整2. 手动调整学习率 总结 调整学习率 调整学习率的目的是&#xff1a;通过调整学习率&#xff0c;优化训练速度、提高训练稳定性、适应不同的训练阶段以及改善模型性能。那么&…

二维四边形网格生成算法:paving(六)行调整 Row Adjustment 与 收尾 Cleanup

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 参考论文&#xff1a;Paving: A new approach to automated quadrilateral mesh generation 关注公众号回复paving可以获得文章链接 paving&#xff08;一&#xff0…

一文讲明白初学者怎么入门大语言模型(LLM)?零基础入门到精通,收藏这篇就够了

关于如何入门LLM&#xff0c;大多数回答都提到了调用API、训练微调和应用。但是大模型更新迭代太快&#xff0c;这个月发布的大模型打榜成功&#xff0c;仅仅过了一个月就被其他模型超越。训练微调也已经不是难事&#xff0c;有大量开源的微调框架&#xff08;llamafactory、fi…

如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内???

&#x1f3c6;本文收录于《全栈Bug调优(实战版)》专栏&#xff0c;主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&am…

基于Springboot+Vue的高校党建基本数据管理系统(含源码+数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 该系统…

芝法酱学习笔记(0.4)——SpringBoot多模块项目打包,resource分离,lib分离,启动脚本

前言 上期讲了如何在windows平台搭建Java后端的开发环境&#xff0c;并给出了一个简单的hello world级别的多模块代码示例。但上期仅仅是在IDEA中运行&#xff0c;和正式的生产环境完全不同。 本期将讲解&#xff0c;如何配置SpringBoot多模块项目的maven打包&#xff0c;并分…

Ubuntu22.04安装VMware Tools

目录 1. 问题2. 在线安装2.1. 更新软件源列表2.2. 更新软件2.3. 下载安装 open-vm-tools-desktop 3. 网络配置3.1 配置网络连接模式3.2 配置静态IP3.3 配置应用3.4 检查IP 1. 问题 安装好 Ubuntu 系统后&#xff0c;想要适配桌面大小等其它功能就需要安装 VMware Tools 这个工…

Linux 文件 IO 管理(第三讲:文件系统)

Linux 文件 IO 管理&#xff08;第三讲&#xff1a;文件系统&#xff09; 进程为什么默认要打开文件描述符为 0&#xff0c;1 和 2 的文件呢&#xff1f;文件系统物理磁盘简单认识存储结构对磁盘存储进行逻辑抽象分组 —— 文件系统Block Bitmapinode Tableinode BitmapGDT(Gro…

Android 利用OSMdroid开发GIS

1、地址 Github地址&#xff1a;https://gitee.com/mirrors/osmdroid Git地址&#xff1a; GitCode - 全球开发者的开源社区,开源代码托管平台 Git下载包地址&#xff1a;Releases osmdroid/osmdroid GitHub 新建项目 osmdroid在线&#xff1a; &#xff08;1&#xff09…

将Mixamo的模型和动画导入UE5

首先进入Mixamo的官网 , 点击 Character 选择一个模型 (当然你也可以自己上传模型/绑定动画) 然后点击下载 , 这个作为带骨骼的模型 选择FBX格式 , T Pose 直接下载 点击 Animations 选择动画 , 搜索 idle 默认站立动画 点击下载 , 格式选择 FBX , 不带模型只要骨骼 , 帧数选6…

低功耗TF卡:录音笔、领夹麦、电池门铃优选

概述 TF卡&#xff0c;也称为Micro SD卡或TransFlash卡&#xff0c;是一种流行的小型存储卡&#xff0c;广泛应用于手机、平板电脑、相机和其他便携式设备。TF卡的尺寸非常小&#xff0c;便于携带和使用&#xff0c;不会占用太多设备空间。而且TF卡提供多种容量选择&#xff0…

Go基础编程 - 15 - 延迟调用(defer)

延迟调用 defer 1. 特性2. 常用用途3. defer 执行顺序&#xff1a;同函数内先进后出4. defer 闭包5. defer 陷阱 上一篇&#xff1a;泛型 1. 特性 1. 关键字 defer 用于注册延迟调用。 2. defer 调用直到 return 前才被执行。 3. 同函数内多个 defer 语句&#xff0c;按先进后…

第17章 协同式任务切换

第17章 协同式任务切换 在多任务系统中&#xff0c;每个任务都有各自的局部描述符表(LDT)和任务状态段(TSS)。 从任务切换的时机来讲&#xff0c;有两种基本的策略&#xff1a; 协同式&#xff1a;从一个任务切换到另一个任务。需要当前任务主动地请求暂时放弃执行权&#x…

好看的首页展示

代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style>/* RESET…

气膜游泳馆:舒适恒温,寒冷季节中的理想游泳场所—轻空间

随着天气逐渐转凉&#xff0c;许多人在秋冬季节减少了户外活动&#xff0c;尤其是游泳。然而&#xff0c;气膜游泳馆为您提供了一种全新的选择&#xff0c;让您即使在寒冷的季节&#xff0c;也能享受畅游的乐趣。凭借其独特的恒温设计和舒适的环境&#xff0c;气膜游泳馆成为了…