摘要: Separate UI-Net Thread 线程分离 我们的线程独立之前: 独立之后: 之所以考虑到将主线程和网络线程分开,是因为接下来要做文件传输,如果和主线程在一起,那么UI可能会卡顿,比如传输音频,大文件之类的。 因此我们将TcpManager也就是网络线程独立到新的线程,不要阻塞我们的主线 阅读全文
posted @ 2025-12-24 23:19 大胖熊哈 阅读(11) 评论(0) 推荐(0)
摘要: Reconnect-LockPrecisionOptimization-AvatarEditBox 断线重连 为了是我们的服务器更具有可恢复性,健壮性,我们必须考虑可能的网络波动导致的短连或者长时间为连接导致自动断连。为此我们设计了断线重连,包括mysql和redis。 实际上这两者的断线重连逻辑是 阅读全文
posted @ 2025-12-24 23:18 大胖熊哈 阅读(6) 评论(0) 推荐(0)
摘要: Chap23-Heartbeat 前情回顾 前文我们实现了跨服踢人逻辑,通过分布式锁锁住不同服务器相同用户登录的操作,保证逻辑的原子性。 今天我们来谈一谈心跳机制,以及为什么要有心跳机制,以及该如何实现心跳机制,而且是分布式情况下心跳配合踢人逻辑该如何实现。 心跳概念 在一个“长连接”(如 TCP 阅读全文
posted @ 2025-12-24 23:18 大胖熊哈 阅读(9) 评论(0) 推荐(0)
摘要: Chap22-DistributedLock_MultiServer 前文我们实现了单服务器踢人的逻辑,通过分布式锁锁住登录过程,在这个期间对用户相关的信息进行更改,主要包括用户id对应的serverip, sessionid等。 同时对用户离线消息进行了处理,也是通过分布式锁锁住退出过程,判断此时 阅读全文
posted @ 2025-12-24 23:18 大胖熊哈 阅读(2) 评论(0) 推荐(0)
摘要: Chap21-DistributedLock_SingleServer 如标题,本节是只针对但服务器的分布式锁的设计。当一个用户在线时,我们需要考虑当另一个设备的相同用户也要登陆时,如何处理两个设备的登陆以及服务器对该用户的状态变化。 分布式锁 在分布式系统中,多个客户端可能同时访问和操作共享资源。 阅读全文
posted @ 2025-12-24 23:18 大胖熊哈 阅读(3) 评论(0) 推荐(0)
摘要: Chap20-Communication 这一节拖得有点久,主要问题是涉及到的字段较多,写的时候太随意奔放导致遗留了很对字段没有设置,出现了很多莫名其妙的bug.因此,在编码的时候一定要捋清信号和槽的关系,每次点击都要处理好你我状态的设置。 本来只是想要简单的客户端请求,服务器给回复,但是考虑到对服 阅读全文
posted @ 2025-12-24 23:18 大胖熊哈 阅读(2) 评论(0) 推荐(0)
摘要: Chap19-NotificationsAndConfirm 这一节要实现的比较多,包括前端的列表加载,确认,接受/拒绝。后端的加载,修改,查询,存储,发送等。 为了简化,这里关于后端要说的一句话就是,如果要发送信息的对象在Redis,也就是在线,那么直接查找uip所在服务器发送,否则就存入数据库。 阅读全文
posted @ 2025-12-24 23:18 大胖熊哈 阅读(4) 评论(0) 推荐(0)
摘要: Chap18-AddFriend 这一节我们完成好友申请和通知的功能(发送好友申请 ,收到好友申请通知)。 为了清晰的分辨我们直接分为前端和后端的修改,而非穿插进行。 前端 添加好友请求 正如上节展示的那样,我们将每个查询到的用户数据都使用一个自定的FriendItem展示出来,在每个FriendI 阅读全文
posted @ 2025-12-24 23:17 大胖熊哈 阅读(5) 评论(0) 推荐(0)
摘要: Chap17-SearchUsers 如标题所见,这一节是关于好友搜索的。分为前端和后端的实现。在此之前,我要先修改mysql的底层封装,即抛弃c的官方api转而使用mysql++的封装。原因很简单,c的api虽然简单,但是代码及流程繁杂无比,为了简化mysql的使用,转而使用cpp的客户端。 my 阅读全文
posted @ 2025-12-24 23:17 大胖熊哈 阅读(42) 评论(0) 推荐(0)
摘要: Chap16-Distributed Service Design 完成了前面的前端的ui,我们开启后端的分布式设计。简而言之就是启动多个服务器,有一个StatusServer服务器用于查找压力最小,连接数量少的服务器,然后将服务器的地址传给前端选择连接。 这多个服务器实际上代码是一样的,除了配置文 阅读全文
posted @ 2025-12-24 23:17 大胖熊哈 阅读(3) 评论(0) 推荐(0)
摘要: Chap07-RedisManager 概念 1. 数据库类型 1.1 基本概念 关系型数据库 - sql 操作数据必须要使用sql语句 数据存储在磁盘 存储的数据量大 举例: - mysql - oracle - sqlite - 文件数据库 - sql server 非关系数据库 - nosql 阅读全文
posted @ 2025-12-24 23:17 大胖熊哈 阅读(4) 评论(0) 推荐(0)
摘要: Chap15-ClientUI 与chap14相隔一段时间,在实现客户端qt的ui界面。此处就是看qt的基础和实现了,并没有着重的分析和记录。只是为了覆盖流程,再次作简单的整体分析。 在之前完成qt登陆注册界面之后,我们通过登陆进入主界面MainInterface.下面是主界面的布局: 首先整体是一 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(2) 评论(0) 推荐(0)
摘要: Chap14-TokenVarifyAndUserManager 流程梳理 先是简单的梳理一下登陆的流程 目前为止,一直到验证token有效性已经完成,现在就是完成之后的内容。 StatusServer的改动 StatusServer添加了grpc服务Login用于验证是否token有效 grpc: 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(2) 评论(0) 推荐(0)
摘要: Chap13-ChatServer ChatServer 这一节我们使用Asio编写ChatServer. 我们从main入手 #include "global/ConfigManager.h" #include "server/AsioPool.h" #include "server/Server 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(1) 评论(0) 推荐(0)
摘要: Chap12-TcpManager 上一节,我们完成了状态服务器,状态服务器用来获取可用的负载小的服务器的信息。 那么我们的Qt前端发送了ID_USER_LOGIN信号之后,posthttp发送登陆请求给GateWayServer。这一步主要是进行验证作用,比如密码邮箱什么的是否正确。正确之后,我们 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(7) 评论(0) 推荐(0)
摘要: Chap11-LoginAndStatus Login 同注册以及忘记密码同理,设计验证、点击后的槽函数、接受到返回信息的槽函数等。 下面是点击登陆后的槽函数 void LoginScreen::do_login_clicked() { QString accountStr = accountEdi 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(5) 评论(0) 推荐(0)
摘要: Chat10-ResetPassword 流程 整体流程那个和忘记密码几乎机制,qt客户端可以直接照搬代码,改一改参数,基本的框架打好了就会非常省时。 #ifndef FORGOTSCREEN_H #define FORGOTSCREEN_H #include <QWidget> #include 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(3) 评论(0) 推荐(0)
摘要: Chap09-MysqlManager Mysql C Connector操作 mysql_init() - 初始化连接句柄 mysql_real_connect() - 连接到数据库 mysql_query() - 执行SQL查询 mysql_store_result() - 存储查询结果 mys 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(16) 评论(0) 推荐(0)
摘要: Chap08-Register 客户端 首先实现按下注册按钮的槽函数 void RegisterScreen::do_register_clicked() { auto res= doVerify(); if(!res){ return; } if (securityCode->text().tri 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(4) 评论(0) 推荐(0)
摘要: Chap06-GateWayServerImproveConcurrencyCapacity 提高前后端通信的并发 原本我们只有一个io_context用来执行所有的操作,包括连接和读写操作。而现在我们要提高他的并发能力,我们就可以创建多个io_context.其中一个是在main函数中创建并且传递 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(9) 评论(0) 推荐(0)
摘要: Chap05-NodejsServer Nodejs基础 非专业,仅因使用在这里补充一些简单的基础。 1. JavaScript 基础语法 变量声明 javascript // var (函数作用域,不推荐) var oldVariable = "value"; // let (块级作用域,可重新赋 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(2) 评论(0) 推荐(0)
摘要: Chap04-GrpcAndConfigManager grpc 选择原因 后端服务之间通信中,为了效率(也可能是惯例),更多的使用grpc进行通信,能够实现了类似本地的无感服务调用.当然也可以选用json,但是效率会低一些. 关于配置grpc,cmake如下. pkg_check_modules( 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(2) 评论(0) 推荐(0)
摘要: Chap03-GateWayServer 网关服务器 GateWayServer在分布式系统中扮演者流量入口和请求调度的关键角色. 在我们的项目分布式系统中,主要是扮演入口的角色,用来进行注册,验证码,登陆等操作. 首先同上一节的要先实现单例类singleton #ifndef SINGLETON_ 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(8) 评论(0) 推荐(0)
摘要: Chap2-CRTP2ImplementHttpManager SingletonTemplate ​ 我们实现发送信息的功能,采用了HTTP协议.大多数情况下,http发送管理类是一个单例类.因此为了之后的复用,我们先是实现了一个单例的模板类,在使用CRTP的形式使HttpManager继承这个模 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(9) 评论(0) 推荐(0)
摘要: Chap1-LoginScreen 简介 本项目为C++全栈聊天项目实战,包括PC端QT界面编程,asio异步服务器设计,beast网络库搭建http网关,nodejs搭建验证服务,各服务间用grpc通信,server和client用asio通信等,也包括用户信息的录入等。实现跨平台设计,先设计wi 阅读全文
posted @ 2025-12-24 23:16 大胖熊哈 阅读(3) 评论(0) 推荐(0)
摘要: Asio8-PacketStickingProblem 粘包问题 分析 粘包问题是指在使用TCP协议进行网络通信时,发送方发送的多个数据包在接收方接收时被"粘"在一起,形成一个大的数据包的现象。这不是TCP协议的bug,而是TCP作为流式协议的固有特性。 发送方: [包1][包2][包3] 接收方: 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(6) 评论(0) 推荐(0)
摘要: Asio9-SendQueueAndEndian 底层的发送流程 字节序问题 计算机内部存储数据的方式有两种:大端序(Big-Endian)和小端序(Little-Endian)。在大端序中,高位字节存储在低地址处,而低位字节存储在高地址处;在小端序中,高位字节存储在高地址处,而低位字节存储在低地址 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(3) 评论(0) 推荐(0)
摘要: Asio11-Json 与protobuf区别 我们上节的protobuf可以做序列化,那么我们为什么又要介绍json格式呢? 原因是,protobuf将信息转化成了二进制的格式,虽然速度快,效率高,可读性却不好。而采用json必然会导致转换效率低,好处是可读性好,也更简单。 一般情况下,proto 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(8) 评论(0) 推荐(0)
摘要: Asio12-HandlePacketStickingProblemSimply 在Asio8中我们处理过粘包的问题,下面的部分的源码: void CSession::HandleRead(const boost::system::error_code& error, size_t bytes_tr 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(3) 评论(0) 推荐(0)
摘要: Asio13-OptimizeTheStructure.md MsgNode 为了方便发送和接受,避免使用错误,我们将MsgNode重新设计,派生出了RecvNode和SendNode,分别用于读取和发送. 基类的MsgNode用于接受头节点,一般情况下设置内部的缓冲区大小为4字节(我们为了方便管理 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(4) 评论(0) 推荐(0)
摘要: Asio14-ImplementLogicSystem.md 单例逻辑类 因为我们的逻辑层一般是单线程(如果多线程,那么在处理资源的情况下,需要对共享资源加锁,更复杂),因此我们实现一个单例模板类,后期可能有其他也需要单例. 首先是一个单例的模板类. #pragma once #include <i 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(4) 评论(0) 推荐(0)
摘要: Asio15-QuitGracefully.md 服务器优雅退出一直是服务器设计必须考虑的一个方向,意在能通过捕获信号使服务器安全退出。我们可以通过asio提供的信号机制绑定回调函数即可实现优雅退出。在主函数中我们添加 int main() { try { boost::asio::io_conte 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(5) 评论(0) 推荐(0)
摘要: Asio16-MultiThreadServicesPool.md 前面的设计,我们对asio的使用都是单线程模式,为了提升网络io并发处理的效率,这一次我们设计多线程模式下asio的使用方式。总体来说asio有两个多线程模型,第一个是启动多个线程,每个线程管理一个iocontext。第二种是只启动 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(7) 评论(0) 推荐(0)
摘要: Asio17-MultiThreadPool.md 区别 Asio-16也是一种多线程模式,那么他跟这一节有什么区别呢? 简单而言,上一节的结构是,n个线程,每个线程一个io_context在运行,相当于底层多个epoll.这一节呢,也是n个线程,但是只有1个线程有io_context在run,底层 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(5) 评论(0) 推荐(0)
摘要: Asio18-Coroutine 什么是协程 简单来说,协程是一个可以暂停执行和恢复执行的函数. 普通函数:调用 → 一直执行到 return 或函数结束 → 返回调用点。调用一次,执行一次,执行完毕后就“烟消云散”,所有局部状态都销毁了。 协程:调用 → 执行到某个点可以暂停(挂起) → 将执行权 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(10) 评论(0) 推荐(0)
摘要: Asio19-CoroutineServer 书接上节,我们要利用协程重构之前的服务器代码. 实际上改动并不大,对于写而言,比较简单,即使回调也比较少,没有改用协程.我们主要在读的时候使用了协程. void Session::Start() { boost::asio::co_spawn(_io_c 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(5) 评论(0) 推荐(0)
摘要: Asio20-BeastServer HttpApi // 创建请求 http::request<http::string_body> req; req.method(http::verb::get); // 设置方法: get, post, put, delete req.target("/api 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(6) 评论(0) 推荐(0)
摘要: Asio21-BeastWebSocket 什么是WebSocket 首先来看HTTP1.0,默认短连接,仅仅客户端可以发送请求,每次发送请求都要携带完整的HTTP头部.也就是说,每次通信都需要三次握手四次挥手,效率低下. HTTP1.1针对这个问题,默认是长连接.只需要一次连接和断开,中间可以多次 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(5) 评论(0) 推荐(0)
摘要: Asio22-GrpcConnection 1.0 什么是rpc RPC(Remote Procedure Call) - 远程过程调用。 简单来说,就是让你能够像调用本地函数一样调用远程服务器上的函数。 2.0 什么是grpc gRPC 是 Google 开发的一个高性能、开源的 RPC 框架。 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(7) 评论(0) 推荐(0)
摘要: Asio10-Protubuf 1.0pkg-config的使用 1.0What 简而言之:**pkg-config** 就是通过读取特定文件的信息来提供 gcc 连接时候所需要的 -I -l 等参数的。 pkg-config 是一个用于在编译应用程序或库时提供编译和链接选项的命令行工具。 它的主要 阅读全文
posted @ 2025-12-24 23:13 大胖熊哈 阅读(2) 评论(0) 推荐(0)