IM项目-----客户端网络通讯流程

文章目录

  • 前言
  • 数据中心类
  • 数据持久化
  • 网络通信类
      • http客户端
      • websocket客户端


前言

对即时通信系统客户端部分的网络通讯流程的总结。


数据中心类

通过model/datacenter.h 中的DataCenter 类来管理所有客⼾端需要的数据.这是⼀个单例类.
这里管理一份数据有两个作用,1.通过本地缓存一份数据避免重复的向服务端获取。2.通过这些变量来实现数据的异步调用。
其中包含有:用户个人信息/会话列表/好友列表/好友申请列表/好友搜索结果列表/历史消息列表。
还有会话ID和会话成员的映射,会话ID和未读消息的映射,会话ID和最近消息列表。

//列出 DataCenter中要组织管理的所有数据//当前客户端登录到服务器对应的登录会话 idQString loginSessionId = "";//当前的用户信息UserInfo* myself = nullptr;// 好友列表QList<UserInfo>* friendList = nullptr;//会话列表QList<ChatSessionInfo>* chatSessionList = nullptr;//记录当前选中的会话是哪个QString currentChatSessionId = "";//记录每个会话中,都有哪些成员(主要针对群聊) key为chatSessionId,value为成员列表QHash<QString,QList<UserInfo>>* memberList = nullptr;//待处理的好友申请列表QList<UserInfo>* applyList = nullptr;//每个会话的最近消息列表,key为chatSessionid,value为消息列表QHash<QString,QList<Message>>* recentMessages = nullptr;//存储每个会话,未读消息的个数,key为ChatSessionId,value为未读消息的个数QHash<QString,int>* unreadMessageCount = nullptr;//用户的好友搜索结果QList<UserInfo>* searchUserResult = nullptr;//历史消息搜索结果QList<Message>* searchMessageResult = nullptr;//短信验证码的验证IdQString currentVerifyCodeId = "";// 让 DataCenter 持有 NetClient 实例.network::NetClient netClient;

同时三个很重要的变量,登录会话ID/当前选中会话/验证码ID。
登录会话ID是登录成功后服务器返回的一个token,用于身份鉴权。往后的每次请求都需要带上这个token。

数据持久化

同时客户但把登录会话ID和会话的未读记录持久化到了文件中。其中登录会话ID的持久化是为了后续实现扩展功能。未读信息个数则是为了实现未读消息提示。

void DataCenter::initDataFile()
{// 构造出文件的路径, 使用 appData 存储文件QString basePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);QString filePath = basePath + "/ChatClient.json";LOG() << "filePath=" << filePath;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();
}

网络通信类

通过network/NetClient.h 中的NetClient 类来管理所有的和服务器通信的内容.NetClient 内部⼜分成httpClient 和websocketClient 两个部分.DataCenter 中会持有NetClient 的指针.

private:model::DataCenter* dataCenter;// http 客户端QNetworkAccessManager httpClient;// websocket 客户端QWebSocket websocketClient;// 序列化器QProtobufSerializer serializer;

http客户端

客户端的通信流程这里总结一下,

  • 首先在dataCenter类中有netClient的实例,我们向服务器发起请求都是通过dataCenter对象来间接调用netClient对象中的http对象向服务器发起请求的。
  • netclient类中的http对象负责发起请求,并通过连接信号槽,接收返回的响应,并判断结果是否正确
  • 在槽函数中对响应中的数据保存到dataCenter中
  • 通过DataCenter发起信号,通知主界面更新UI。
  • 至此就实现了异步的网络请求。
    在这里插入图片描述

websocket客户端

由于websocket需要建立tcp长连接之后才可以通信,所以在客户端登录成功后,需要进行websocket的初始化。这里通过open函数与服务器建立连接。绑定信号槽在连接建立成功后会给服务器发送身份验证请求。服务器需要建立用户ID与websocket连接的映射管理。

通过连接信号槽处理二进制消息,服务器只会给我们发送二进制消息。

void NetClient::initWebSocket()
{//1.准备好所有需要的信号槽connect(&websocketClient,&QWebSocket::connected,this,[=]() {qDebug() << "webSocket 连接成功";//连接建立成功后,进行身份认证sendAuth();});connect(&websocketClient,&QWebSocket::disconnected,this,[=]() {qDebug() << "webSocket 连接断开";});connect(&websocketClient,&QWebSocket::errorOccurred,this,[=](QAbstractSocket::SocketError error) {qDebug() << "webSocket 连接出错" << error;});connect(&websocketClient,&QWebSocket::textMessageReceived,this,[=](const QString& message) {qDebug() << "webSocket 收到文本消息!" << message;});connect(&websocketClient,&QWebSocket::binaryMessageReceived,this,[=](const QByteArray& byteArray) {qDebug() << "webSocket 收到二进制消息!" << byteArray.length();//这里是webSocket接收数据的入口//反序列化出 protoBuf对象lkm_im::NotifyMessage notifyMessage;notifyMessage.deserialize(&serializer,byteArray);handleWsResponse(notifyMessage);});//2.和服务器真正建立连接websocketClient.open(WEBSOCKET_URL);
}

websocket通信的流程总结一下,在这里的信号槽是处理的入口,通过反序列化构建对象。
通过事件类型进行分类处理,对返回的数据通过dataCenter进行保存,然后通过dataCenter发送信号,通知主界面进行更新UI。

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

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

相关文章

软件测试—— Selenium 常用函数(一)

前一篇文章&#xff1a;软件测试 —— 自动化基础-CSDN博客 目录 前言 一、窗口 1.屏幕截图 2.切换窗口 3.窗口设置大小 4.关闭窗口 二、等待 1.等待意义 2.强制等待 3.隐式等待 4.显式等待 总结 前言 在前一篇文章中&#xff0c;我们介绍了自动化的一些基础知识&a…

WebSocket详解、WebSocket入门案例

目录 1.1 WebSocket介绍 http协议&#xff1a; webSocket协议&#xff1a; 1.2WebSocket协议&#xff1a; 1.3客户端&#xff08;浏览器&#xff09;实现 1.3.2 WebSocket对象的相关事宜&#xff1a; 1.3.3 WebSOcket方法 1.4 服务端实现 服务端如何接收客户端发送的请…

【图像分割】SegFormer: Simple and Efficient Design for Semantic Segmentation with Transformers

SegFormer: Simple and Efficient Design for Semantic Segmentation with Transformers 论文链接&#xff1a;http://arxiv.org/abs/2105.15203 代码链接&#xff1a;https://github.com/NVlabs/SegFormer 一、摘要 文中提出了SegFormer&#xff0c;一个简单、高效且强大的…

HarmonyOS知识点

HarmonyOS应用模型Stage&FA 、ArkTS、ArkUI Stage模型&#xff1a; Module - UIAbility - Page - component 装饰器Entry、Component、CustomDialog、State、关键字struct、函数build() 系统组件&#xff08;Text Column Row Scroll&#xff09;、自定义组件 、组件复用、…

速盾:CDN是否支持屏蔽IP?

CDN&#xff08;内容分发网络&#xff09;是一种用于提高网站性能和可靠性的技术&#xff0c;通过将内容分发到距离终端用户更近的节点&#xff0c;减少了数据传输的延迟并提高了用户体验。在CDN中&#xff0c;屏蔽IP是一项重要的功能&#xff0c;可以帮助网站屏蔽无效或恶意请…

Linux修改/etc/hosts不起作用(ping: xxx: Name or service not known)的解决方法——开启NSCD

​ 问题描述 起因是我在实验室云资源池的一台虚拟机&#xff08;CentOS 8.5&#xff09;上的/etc/hosts文件中为Fabric网络节点的域名指定了IP&#xff1a; IP可以ping通&#xff0c;但是ping域名时提示ping: xxx: Name or service not known。 问题本身应该是Linux通用的&a…

OpenTelemetry 赋能DevOps流程的可观测性革命

原作者&#xff1a;天颇 原出处&#xff1a;微信公众号 乘云数字DATABUFF 原文地址&#xff1a;https://mp.weixin.qq.com/s/D_f31EBtLu7Rr0gahuF-bw 引言 在当今快节奏的软件开发和运维环境中&#xff0c;DevOps 已经成为主流&#xff0c;它通过整合开发和运维流程&#xff0…

学了Arcgis的水文分析——捕捉倾泻点,河流提取与河网分级,3D图层转要素失败的解决方法,测量学综合实习网站存着

ArcGIS水文分析实战教程&#xff08;7&#xff09;细说流域提取_汇流域栅格-CSDN博客 ArcGIS水文分析实战教程&#xff08;6&#xff09;河流提取与河网分级_arcgis的dem河流分级-CSDN博客 ArcGIS水文分析实战教程&#xff08;5&#xff09;细说流向与流量-CSDN博客 ArcGIS …

windows 和 linux检查操作系统基本信息

windows检查操作系统基本信息 systeminfolinux检查操作系统基本信息 获取系统位数 getconf LONG_BIT查询操作系统release信息 lsb_release -a查询系统信息 cat /etc/issue查询系统名称 uname -a

gitHub常用操作

gitHub常用操作 1、把项目拉下来2、添加上游仓库3、进入分支4、从上游仓库拉取更新 1、把项目拉下来 在对应项目的右上角点击fork&#xff0c;fork下来&#xff1a;将远程仓库复制到个人仓库 在创建好的分支文件夹下使用 git clone自己远程仓库下的http地址&#xff08;fork…

使用SaaS化的Aurora应用快速搭建私人ChatGPT助手

使用SaaS化的Aurora应用快速搭建私人ChatGPT助手 简介&#xff1a; Aurora是一个带UI且免费的GPT私人聊天助手&#xff0c;可切换GPT-3.5&#xff0c;4&#xff0c;4o等常用版本。用户可通过部署Aurora&#xff0c;快速打造自己专属的AI助手。阿里云计算巢已将Aurora打包为SaaS…

Android开发实战班 -网络编程 - Retrofit 网络请求 + OkHttp 使用详解

在现代 Android 应用开发中&#xff0c;网络编程是必不可少的一部分。Retrofit 是 Square 公司推出的一款类型安全的 HTTP 客户端库&#xff0c;简化了与 RESTful API 的交互。Retrofit 基于 OkHttp&#xff0c;并提供了简洁的接口定义和强大的功能&#xff0c;如异步请求、请求…

ASFSSA-VMD多策略改进的麻雀搜索算法优化变分模态分解

ASFSSA-VMD多策略改进的麻雀搜索算法优化变分模态分解 目录 ASFSSA-VMD多策略改进的麻雀搜索算法优化变分模态分解效果分析基本介绍程序设计参考资料效果分析 基本介绍 (创新独家)ASFSSA-VMD多策略改进的麻雀搜索算法优化变分模 态分解ASFSSA-VMD:优化VMD分解层数K和惩罚因子a…

Unity脚本基础规则

Unity脚本基础规则 如何在Unity中创建一个脚本文件&#xff1f; 在Project窗口中的Assets目录下&#xff0c;选择合适的文件夹&#xff0c;右键&#xff0c;选择第一个Create&#xff0c;在新出现的一栏中选择C# Script&#xff0c;此时文件夹内会出现C#脚本图标&#xff0c;…

【新华妙笔-注册/登录安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

Dart:字符串

字符串&#xff1a;单双引号 String c hello \c\; // hello c&#xff0c;单引号中使用单引号&#xff0c;需要转义\ String d "hello c"; // hello c&#xff0c;双引号中使用单引号&#xff0c;不需要转义 String e "hello \“c\”"; // hell…

使用vscode+expo+Android夜神模拟器运行react-native项目

1.进入夜神模拟器安装路径下的bin目录 2.输入命令&#xff0c;连接Android Studio 启动夜神模拟器后&#xff0c; 打开安装目录的bin文件夹执行下面的命令&#xff0c;只需执行一次&#xff09; nox_adb.exe connect 127.0.0.1:62001adb connect 127.0.0.1:62001 3.运行项目…

从0安装mysql server

安装 MySQL Server 首先,你需要在 Ubuntu 上安装 MySQL 服务器。运行以下命令来安装:sudo apt update sudo apt install mysql-server安装完成后,MySQL 服务会自动启动。你可以通过以下命令检查 MySQL 服务是否正在运行: sudo systemctl status mysql如果 MySQL 正在运行,…

自动计算机视觉功能技术方向

近年来&#xff0c;随着自动计算机视觉功能的不断发展&#xff08;如跟踪、目标/活动识别等&#xff09;的技术方向&#xff0c;这些技术在无人机应用领域中的重要性也日益凸显。同时&#xff0c;得益于低成本商用无人机的日益普及&#xff0c;这些技术得到了快速的推广和应用。…

Linux进阶:软件安装、网络操作、端口、进程等

软件安装 yum 和 apt 均需要root权限 CentOS系统使用&#xff1a; yum [install remove search] [-y] 软件名称 install 安装remove 卸载search 搜索-y&#xff0c;自动确认 Ubuntu系统使用 apt [install remove search] [-y] 软件名称 install 安装remove 卸载search 搜索-y&…