当前位置:网站首页>集群聊天服务器:项目问题汇总
集群聊天服务器:项目问题汇总
2022-07-25 07:08:00 【_索伦】
1. 简单描述一下你的项目
该项目是一个网络服务器的项目,它分为以下模块。
- 第一个是网络模块,采用的是muduo网络库来设计,该网络库的优点就是解耦了网络模块代码和业务模块代码,能够让开发者专注于业务的开发。
- 业务层运用了一些C++11的一些技术,比如map、绑定器等,主要是做了一个消息ID以及这个消息发生后的一个回调操作的绑定,回调机制。当网络I/O给我吐出来一个消息请求的时候,根据请求解析出Json,得到消息ID,然后处理该消息。
- 数据存储层运用了MySQL,对项目上的一些关键数据进行了落地,比如说用户的账号、离线消息,群组消息等,都是在数据库存储。并实现了数据库连接池,省去大量三次握手四次挥手过程,提高对数据库的访问效率。
以上是单机服务器的基本模块,但单机服务器并发能力有限,所以部署多台服务器,就要配置Nginx TCP负载均衡(因为是长连接,所以是基于TCP的)。
各个服务器有不同的用户注册,那这些不同服务器的用户想要通信的话,项目里引入了redis的发布-订阅。
2. 数据明文传输的安全问题
在该项目中,使用的是HTTP明文传输,那么保证安全问题就是进行加密操作。
对称加密
非对称加密
对称加密:加密方和解密方用同一个密钥key。
发送方发送前对明文数据加密生成密文,解密方利用密钥还原成明文。
优点是效率高,例如AES加解密算法

非对称加密:有公钥和私钥两种密钥,而且是一一配对的。
加密复杂,效率慢,但是安全。例如RSA加密算法。
具体实现:
因为非对称加密效率低,所以采用混合加密。
在编写代码时在客户端和服务器生成公钥和私钥,然后客户端和服务器三次握手建立连接后,客户端利用RSA公钥把对称加密的AES密钥加密成密文,发送到服务器后服务器利用RSA私钥解密,得到这个AES私钥,然后给客户端回复一个OK,客户端和服务器就都拥有了AES私钥,那么在后续的数据传输中,就可以利用AES对称加密来对明文加密了。
还有个问题就是有那么多客户要与服务器连接,那么每个客户端都要与服务器生成AES密钥,这就需要服务器把每个客户端的密钥存储在数据库,每次有数据传输过来,为了方便找到对应的密钥,可以只把数据的重要部分message body进行加密,而userid不加密,服务器可以根据userid找到对应的密钥。

3. 客户端消息如何按序显示
在通信过程中会有这个问题,即client1发送给client2的消息,不会按顺序到达,因为在传输过程中可能会经过不同的路由节点。示例:消息是无序的

解决方案:
给每个消息都添加一个序列号 seq,接收方维护每一个好友的消息序列号seq。
示例:
接收方维护每个好友的消息seq,初始化为0,当接收到消息时,查看该消息的seq,如果不是0,则对当前消息进行缓存,等到序列号为0的消息接收到后,对维护好友的seq++,再去查看缓存的消息。

4. server端如何感知客户端的状态
如果网络堵塞严重,ChatServer端如何感知客户端在线还是掉线?
解决方案:心跳机制
让心跳业务绑定UDP8080号端口,server端启动一个心跳计时器,客户端给服务器发送一次heartbeat消息类型,就对该用户的计时器减一,超时的话就加一,一般情况下,计时器的值会在(-1, 0, 1)之间变化。
如果某个client的心跳计时器超过5,就判定该client已经掉线了,那么就释放这个client所有的连接以及其他资源。
一般情况下,对于这种类似于聊天服务器都是长连接,都会在业务层设计一个心跳机制。

提到这个心跳机制,那还有个问题就是TCP协议的keepalive机制。
示例:在client与server建立TCP连接后,但双方没有传输数据,那么server端如何得知client的状态,client到底是掉线了,还是连接正常只是不传数据,还是链路断开了?
在Linux中,我们可以通过代码启用一个socket的心跳检测。
// on 为1时表示打开keepalive选项,默认为0
int on = 1;
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
但keepalive默认发送心跳检测的时间间隔是7200s,时间太长,不具有实用性。
可以设置相关的三个选项来改变这个时间间隔,分别是:
- TCP_KEEPIDLE
- TCP_KEEPINTVL
- TCP_KEEPCNT
示例:
// 发送keepalive报文的时间间隔
int val = 7200;
setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val));
// 两次重试报文的的时间间隔
int interval = 75;
setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
int cnt = 9;
setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt));
TCP_KEEPIDLE选项设置了发送keepalive报文的时间间隔,发送时如果对端回复ACK,则本端TCP协议栈认为该连接依然存活,继续等待7200s后再发送keepalive报文;如果对端回复RESET,则说明对端进程已经重启,本端的应用程序应该关闭该连接。
如果对端没有任何回复,则本端进行重试,如果重试9次(TCP_KEEPCNT)仍然不可达,前后重试的间隔为75s(TCP_KEEPINTVL),则向应用程序返回TIMEOUT(无任何应答)或EHOST错误信息。
边栏推荐
- 【SemiDrive源码分析】【驱动BringUp】38 - NorFlash & eMMC分区配置
- With apple not making money, the 2trillion "fruit chain" abandons "fruit" and embraces "special"
- 阿里云镜像地址&网易云镜像
- Thread 类的基本用法
- 2022天工杯CTF---crypto1 wp
- 数据提交类型 Request Payload 与 Form Data 的区别总结
- 【每日一题】剑指 Offer II 115. 重建序列
- Kubernates-1.24.2 (latest version) + containerd + nexus
- EFCore高级Saas系统下单DbContext如何支持不同数据库的迁移
- ArgoCD 用户管理、RBAC 控制、脚本登录、App 同步
猜你喜欢
![[computer explanation] NVIDIA released geforce RTX Super Series graphics cards, and the benefits of game players are coming!](/img/11/24f92b4362026ec2c01492d195560b.png)
[computer explanation] NVIDIA released geforce RTX Super Series graphics cards, and the benefits of game players are coming!

New tea, start "fighting in groups"

LeetCode46全排列(回溯入门)

With apple not making money, the 2trillion "fruit chain" abandons "fruit" and embraces "special"

How to learn C language?

Health clock in daily reminder tired? Then let automation help you -- hiflow, application connection automation assistant

Common mode inductance has been heard many times, but what principle do you really understand?

Insight into mobile application operation growth in 2022 white paper: the way to "break the situation" in the era of diminishing traffic dividends

如何学习 C 语言?

代码中的软件工程:正则表达式十步通关
随机推荐
EFCore高级Saas系统下单DbContext如何支持不同数据库的迁移
Will eating fermented steamed bread hurt your body
【愚公系列】2022年7月 Go教学课程 016-运算符之逻辑运算符和其他运算符
Special analysis of data security construction in banking industry
Teach you to use cann to convert photos into cartoon style
Wechat applet request requests to carry cookies to verify whether it has logged in
Traffic is not the most important thing for the metauniverse. Whether it can really change the traditional way of life and production is the most important
Talk about practice, do solid work, and become practical: tour the digitalized land of China
A scene application of 2D animation
Thread 类的基本用法
Argocd user management, RBAC control, script login, APP synchronization
Example demonstration of math.random() random function
微信小程序wx.request接口
Openatom xuprechain open source biweekly report | 2022.7.11-2022.7.22
Lpad() function and (row_number() over (order by) +...)
Not only log collection, but also the installation, configuration and use of project monitoring tool sentry
机器学习两周学习成果
【电脑讲解】NVIDIA发布GeForce RTX SUPER系列显卡,游戏玩家福利来了!
【每日一题】剑指 Offer II 115. 重建序列
Wechat applet switchtab transmit parameters and receive parameters