集群聊天服务器——逻辑梳理
网络聊天服务器项目,该项目分为4个模块:
- 首先是网络模块:我使用了muduo高性能网络库,解耦合网络与业务之间这两部分代码,可以更加专注与业务的功能开发
- 其次是服务层模块:我使用了基于C++11的技术比如绑定器和map,绑定器实现了用户发送的消息id类型回调业务功能函数的机制(当网络i/o发送消息请求后,通过解析json消息获取消息id 回调业务功能函数)
- 然后是数据存储模块:我使用了MySQL数据库存储关键的信息(用户账户、离线消息列表、群组信息、好友列表等)由客户端的功能请求进行增删改查
以上是单机服务器的模块设计,但是单机服务器的并发数量是有限的,所以我采用了集群服务器经行并发能力扩展
4.最后在多台服务器部署,基于Tcp 协议搭建的C/S 通信,所以我使用了Nginx Tcp负载均衡,保持长连接状态,并且引入Redis 的发布订阅功能实现跨服务器间通信
1. 客户端:
1.1. 两个模块:
1.1.1. 负责用户登录、注册、退出功能
作为客户端连接服务器成功后的首界面展示:提供以上三种服务
客户端设计模式:主线线程专注于信息的发送、子线程负责接受信息
将具体功能的所需参数进行json(key-value键值对存储文本形式)序列化发送给服务器
个别服务需要服务器返回方法返回值状态信息,(登录成功、信息注册成功)?多线程协调实现
由主线程发送后,阻塞获取信号量,子线程此时接受服务器返回的json对象,由json中的服务方法枚举id,分类细化具体的功能实现业务逻辑,将服务方法调用的状态写入最后将信号量释放,主函数则可以通过子线程写入的状态进行下一步工作
登陆成功后进入功能菜单:
1.1.2. 负责聊天服务器业务功能:添加好友信息、创建群组、加入群组、单人聊天、群组聊天
将功能函数处理为map表形式<存储函数方法名称,方法绑定器>,循环处理客户端的输入的方法请求,在循环中未使用switch_case而是map+bind回调,适应于程序开发中的开闭原则,对修改关闭,对开发扩展开放;
该部分函数主要处理用户的功能以及输入的参数,封装为json 对象(服务器协商的通信规则:方法枚举id的标识,与方法请求一致的参数列表)发送给服务器
auto it = commandHandlerMap.find(command);
if (it == commandHandlerMap.end())
//error// 调用相应命令的事件处理回调,mainMenu对修改封闭,添加新功能不需要修改该函数
it->second(clientfd, commandbuf.substr(idx + 1, commandbuf.size() - idx));
// 调用命令处理方法
2. 服务器:
2.1. 服务器需要处理信息转发、功能性数据的存储、查询、更新服务
解决基于数据库的功能服务问题:MySQL
解决高并发场景下数据收发问题:muduo 静态网络库
解决跨服务器通信问题 :Redis发布订阅问题
解决负载均衡问题:Nginx_基于Tcp长连接的负载均衡问题
2.2. 主要基于以上内容将服务器划分出:
server、service、db、model、redis、public 六个模块
2.2.1. server——muduo网络:
基于epoll+多线程的机制实现高并发需求
在该模块中设置四个工作线程,其中一个处理连接回调,在连接异常的场景下关闭连接,余下三个线程为工作线程,完成将接收的字符基于json-parse反序列化发送给service,基于服务方法id,回调具体的处理函数
2.2.2. db:
数据库的接口API ,创建初始化、数据库连接、
数据更新、数据查询query
// 初始化数据库连接_conn = mysql_init(nullptr);// 释放数据库连接资源
if (_conn != nullptr)mysql_close(_conn);// 连接数据库MYSQL *p = mysql_real_connect(_conn, server.c_str(), user.c_str(),password.c_str(), dbname.c_str(), 3306, nullptr, 0);// 更新操作
mysql_query(_conn, sql.c_str())// 查询操作
mysql_query(_conn, sql.c_str())return mysql_use_result(_conn);
2.2.3. model:
该模块用来实现用户需求与服务器数据库交互增、删、改、查问题
以举例:
// 添加好友关系,在好友数据表中添加一条记录
sprintf(sql, "insert into friend values(%d, %d)", userid, friendid);// 返回用户好友列表,联合查询用户表和好友表,将结果插入vector并用返回
sprintf(sql, "select a.id,a.name,a.state from user a /
inner join friend b on b.friendid = a.id where b.userid=%d", userid);// 删除用户的离线消息,删除离线列表的一条信息
sprintf(sql, "delete from offlinemessage where userid=%d", userid);// 更新用户的状态信息
sprintf(sql, "update user set state = '%s' where id = %d",/user.getState().c_str(), user.getId());
2.2.4. redis:
基于Redis发布订阅问题,解决跨服务器通信问题:
初始化发布上下文、订阅上下文,进行连接、向指定chennel 发布、订阅,结束订阅、断开连接
2.2.5. service:
设置方法map集合<方法id,方法handler绑定器>
设置用户连接map集合<用户id,连接TcpConnectionPtr接口>,将所有方法的枚举值,函数方法绑定器插入map表,连接Redis服务器、MySQL 数据库
基于具体的方法选择,结合底层存储的用户数据(查询、插入、删除)完成登录、注册、注销用户;
结合model模块下的函数具体结合用户需求完善功能函数;
聊天服务:查询用户的连接信息,在本服务器时转发聊天信息,不在本台服务器,检查数据库的用户登陆状态,未登录存储离线信息表,登录则发布到Redis的发布队列
登录问题:(最复杂)
从json对象解析得到登录id、密码
在用户信息表中查询该id的所属对象并比对密码,不一致将封装json返回原因;
一致时检查登陆状态避免重复登陆,继而更新用户的登陆状态;
在用户登录map中插入其连接信息;
订阅Redis对该id 为chennel的消息;
打印该用户的离线消息;
将该对象的好友信息封装为vector存储的json序列化文本信息,作为返回的json-response对象key-value 存储的对象之一;群组信息如上;
最后返回最后的json-response序列化内容。
2.2.6. public:
保存服务方法的枚举信息,将每一服务名称与id一一对应
相关文章:

集群聊天服务器——逻辑梳理
网络聊天服务器项目,该项目分为4个模块: 首先是网络模块:我使用了muduo高性能网络库,解耦合网络与业务之间这两部分代码,可以更加专注与业务的功能开发其次是服务层模块:我使用了基于C11的技术比如绑定器和…...

10 最长回文子串、买卖股票的最好时机(一)、[NOIP2002 普及组] 过河卒24_10_30
这里写目录标题 cpp 101 最长回文子串1.1 题目1.2 思路1.3 程序实现 2 买卖股票的最好时机(一)2.1 题目2.2 思路2.3 程序实现2.4 程序实现 – 优化 3 [NOIP2002 普及组] 过河卒3.1题目3.2 思路3.3程序实现 – dp 4 题目链接 cpp 10 1 最长回文子串 1.1 题目 1.2 思路 读完了…...

Handler、Looper、message进阶知识
Android Handler、Looper、Message的进阶知识 在Android开发中,Handler、Looper和Message机制是多线程通信的核心。为了深入理解并优化它们的使用,尤其是在高并发和UI性能优化中,可以利用一些高级特性。 1. Handler的高阶知识 Handler在基本…...
一文理解决策树:原理、数学公式与全流程实战讲解
一、背景与来源 决策树(Decision Tree)是一种常见的机器学习算法,主要用于分类和回归问题。其概念来源于统计学和决策论,能够直观地模拟人类的决策过程。最早的决策树算法之一是 1963 年由 Hunt 等人提出的,该算法逐渐…...

day04-LogStash扩展
1.LogStash性能不稳定(某天关闭后,再次启动就非常慢),所以后面我们用Filebeat。2.先禁用 # geoip { # source > "clientip" # }3.在生产中要是用nignx服务或tomcat服务我们用EFK架构就可以排查技巧观察点 LogS…...

Linux云计算 |【第五阶段】CLOUD-DAY4
主要内容: Linux容器基础、安装Docker、镜像管理、容器管理、容器部署应用 一、容器介绍 容器(Container) 是一种轻量级的虚拟化技术,用于在操作系统级别隔离应用程序及其依赖项。容器允许开发者在同一台主机上运行多个独立的应…...

为什么QNAP威联通NAS的APP center无法安装APP?
创作立场:原创不易,拒绝搬运~ hello大家好,我是你们的老伙伴,稳重的大王~ 如题,大王带你一起来排查一下,可能遇到的问题。如有帮助,请给个关注鼓励,互谢~ 1 首先,安装…...

Kafka 基础入门
文章内容是学习过程中的知识总结,如有纰漏,欢迎指正 文章目录 前言 1. 核心概念 1.1 Producer 1.2 broker 1.3 consumer 1.4 zookeeper 1.5 controller 1.6 Cluster 2. 逻辑组件 2.1 Topic 2.2 Partition 2.3 Replication 2.4 leader & follower 3. …...
网络问题排查
1.ping 域名发现响应时间很长,怎么分析卡在哪里? 当你在 Linux 系统中 ping 一个域名并发现响应时间很长时,可能存在于多个环节的问题。以下是一些步骤和工具,可以帮助你分析和诊断问题出在哪里: 1. 检查 DNS 解析时…...

webGlL变量的声明与使用
抢先观看: 变量的声明格式:<存储限定符><类型限定符><变量名> 存储限定符:const, attribute, uniform, varying, buffer。 类型限定符:void, bool, int, float, double, vec2, vec3, vec4, mat2, mat3, mat4, s…...

qt的c++环境配置和c++基础【正点原子】嵌入式Qt5 C++开发视频
QT c 环境配置和c基础 c环境配置和工程创建 1.配置步骤 2.新建qt 工程目录和工程 3.重启qt后打开最近的qt项目 c基础-类和对象 1.什么是类和对象 A.类的定义 B.类的结构表示 C.类的访问权限 D.对象的定义 E.类和对象的关系 2.类…...

中间件安全(三)
本文仅作为学习参考使用,本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 前言: 本文主要讲解apache命令执行漏洞(cve_2021_41773)。 靶场链接:Vulfocus 漏洞威胁分析平台 一,漏洞简介。 cve_2021_41773漏洞…...

唱戏机上的内存卡怎么加密?教你两个方法
唱戏机是中老年人群休闲时光的好伴侣。然而,很多唱戏机商家都会面临一个困扰:如何保护唱戏机上内存卡中的音频,避免他人随意复制呢?今天这篇文章看完,问题将迎刃而解~ 数据隐藏 将内存卡插到电脑上,对卡里…...

MyBatis 源码分析 - SQL执行过程(三)之 ResultSetHandler
MyBatis的SQL执行过程 在前面一系列的文档中,我已经分析了 MyBatis 的基础支持层以及整个的初始化过程,此时 MyBatis 已经处于就绪状态了,等待使用者发号施令了 那么接下来我们来看看它执行SQL的整个过程,该过程比较复杂ÿ…...
webpack解决使用window.open方法打开history路由页面提示404的问题
问题: 一般情况下应该使用history.push(/ssh)打开history路由页面 但项目中使用window.open(/ssh),然后使用new WebSocket进行通信 开发环境下启动项目后,/ssh页面打开却显示cannot get /ssh,控制台提示404 排查问题: 在React开发环境中使用 window.open 打开路由页面时&a…...

怎么把视频的声音转化为文字免费?7个小妙招,视频转文字轻松解决!
您是否也曾在做会议记录时,希望能免费把视频的声音转化为文字呢?在如今我们的办公生活中,用视频记录会议、记录的生活似乎已经成为了我们一项必备技能,但也并非所有人都能轻松获取视频中的信息。尤其是有着听力障碍的人群…...

【无标题】2024年第五届 MathorCup 数学应用挑战赛——大数据竞赛赛题
2024年第五届 MathorCup 数学应用挑战赛——大数据竞赛赛题已发布~,本届初赛时间为:2024年10月25日18:00至2024年11月1日20:00。本次赛题分为A,B两道,所有参赛队从赛道 A、B 中任选一题作答。在报名系统内选择自己队伍的赛道时&am…...

新能源行业必会基础知识---电力现货问答---第9问---什么是输电权?什么是输电权市场?
新能源行业必会基础知识-----电力现货问答-----主目录-----持续更新https://blog.csdn.net/grd_java/article/details/142909208 虽然这本书已经出来有几年了,现货市场已经产生了一定变化,但是原理还是相通的。还是推荐大家买来这本书进行阅读观看&#…...

视频文案素材获取渠道分享
做视频时为文案发愁?别担心!今天为大家推荐几个实用的视频文案素材网站,让你灵感爆棚,轻松创作文案。 蛙学网 首先要推荐的是蛙学网。作为专业短视频素材库,不仅有修牛蹄、解压视频等热门素材,还为短视频创…...

尚硅谷-react教程-求和案例-数据共享(下篇)-完成数据共享-笔记
#1024程序员节|征文# public/index.html <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>redux</title></head><body><div id"root"></div></body> </html&…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...