# chatsystem **Repository Path**: chicken-c/chatsystem ## Basic Information - **Project Name**: chatsystem - **Description**: 基于QT的全栈即时通讯系统 - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-08-05 - **Last Updated**: 2025-04-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: 项目, Grpc, etcd, es, ODB ## README # 写在前面 之前已经用Qt完成过一个即时通讯系统的项目了: [Qt-即使通讯系统](https://gitee.com/chicken-c/communication-system) 在上一个项目中使用的是单体架构,通过LibEvent来搭建后台服务器,序列化框架使用的是JsonCpp.通过自定义协议在应用层完成对tcp的粘包处理,在前后端交互接口上设计的也比较简单。只支持文本消息和文件消息,且没有对消息进行持久化存储。 本项目是对上一个项目的重构,是对近期所学知识的一个整合。在该项目中学习到了微服务相关知识,包括服务和服务之间通过rpc通信,服务之间通过注册中心,进行服务注册和服务发现感知对方的存在,包括服务之间通过MQ进行解耦合等等,以及引入了ES来进行更高级的文档存储和搜索的服务,使用了ODB来对数据库进行操作。通过该项目对分布式系统有了更深刻的理解。 在客户端方面,通过布局管理器来对界面进行布局管理,使用了大量的自定义控件来实现复杂的界面效果,通过QSS来对界面进行美化,通过信号槽来实现各种人机交互。基于protobuf序列化反序列化使用了Http和Websocket来进行异步的网络通信,使用了QPainter API实现了本地的随机验证码的绘制,使用了Qt的多媒体组件来使用音频的录制播放,对于继承和多态有了更深的理解,应用了单例模式和工厂模式来对代码进行组织。 # 项目架构 该项目是微服务项目,分为7个子服务,由一个网关子服务和6个业务子服务组成. 作为网关,负责和客户端进行直接对接,并在鉴别权限之后,通过etcd注册中心获取其他业务子服务的主机地址,进行一个rpc的调用,业务子服务进行业务处理,再将结果返回给网关,由网关进行一个响应。网关子服务同时包含有用户身份验证的功能,避免被恶意请求所攻击,客户端在登录成功后需要携带一个token字段,如果没有这个字段,那么不予提供任何服务. 其中网关又分成两种协议进行通信,分别是HTTP协议和WebSocket协议 Http协议:传统的业务必然使用Http协议就可以,http更适合对外提供开放性接口,便于跨平台兼容。以后如果需要支持web端,那么可以很方便的进行一个适配. WebSocket协议:在聊天室项目中,也有一些服务是Http做不到的,需要服务器主动推送资源(消息即使推送,好友申请信息的推送,创建群聊的推送等),而这对于Http协议来说是做不到的(或不方便做到),即使在Http后续的优化中引入了主动推送部分资源的功能,但是也依旧不能满足需要。所以就引入了这个WebSocket协议在这个项目中,直接使用WebSocket来进行服务,可以向客户端发送数据。 # 实现的功能 1. 用户注册:用户输入用户名(昵称),以及密码进行用户名的注册 2. 用户登录:用户通过用户名和密码进行登录 3. 短信验证码获取:当用户通过手机号注册或登录的时候,需要获取短信验证码 4. 手机号注册:用户输入手机号和短信验证码进行手机号的用户注册 5. 手机号登录:用户输入手机号和短信验证码进行手机号的用户登录 6. 用户信息获取:当用户登录之后,获取个人信息进行展示 7. 头像修改:设置用户头像 8. 昵称修改:设置用户昵称 9. 签名修改:设置用户签名 10. 手机号修改:修改用户的绑定手机号 11. 好友列表的获取:当用户登录成功之后,获取自己好友列表进行展示 12. 申请好友:搜索用户之后,点击申请好友,向对方发送好友申请 13. 待处理申请的获取:当用户登录成功之后,会获取离线的好友申请请求以待处理 14. 好友申请的处理:针对收到的好友申请进行同意/拒绝的处理 15. 删除好友:删除当前好友列表中的好友 16. 用户搜索:可以进行用户的搜索用于申请好友 17. 聊天会话列表的获取:每个单人/多人聊天都有一个聊天会话,在登录成功后可以 获取聊天会话,查看历史的消息以及对方的各项信息 18. 多人聊天会话的创建:单人聊天会话在对方同意好友时创建,而多人会话需要调 用该接口进行手动创建 19. 聊天成员列表的获取:多人聊天会话中,可以点击查看群成员按钮,查看群成员信息 20. 发送聊天消息:在聊天框输入内容后点击发送,则向服务器发送消息聊天请求 21. 获取历史消息: a. 获取最近 N 条消息:用于登录成功后,点击对方头像打开聊天框时显示最近的消息 b. 获取指定时间段内的消息:用户可以进行聊天消息的按时间搜索 22. 消息搜索:用户可以进行聊天消息的关键字搜索 23. 文件的上传 24. 文件的下载 25. 语音消息的文字转换:客户端进行语音消息的文字转换。 # 通信协议及接口的设计 上面介绍的实现的功能都是一个一个需要在服务端实现的接口。我们已经直到了客户端和服务端进行通信通过http/ws协议通信,而内部服务器之间使用rpc协议进行通信。那么通信协议的设计就很重要了. #### 网关http接口 http协议包含首行,请求头,请求体三个重要部分. 其中首行规定了请求方法和请求url,在项目中我们呢规定所有的请求方法同一使用post方法. 关于url,我们采用/service/{service_name}/{Business} 的 格式要求. ``` 获取好友列表 /service/friend/get_friend_list 获取好友信息 /service/friend/get_friend_info 获取单个文件数据 /service/file/get_single_file 获取多个文件数据 /service/file/get_multi_file 用户名密码登录 /service/user/username_login 手机号码注册 /service/user/phone_register ``` 请求体采用protobuf的序列化方式进行定义。 而请求体和我们后端的rpc接口的request和response一致,也就是后端在http接口中可直接调用rpc请求进行一个复用. # 项目的不足 这个项目主要的点在于: (1)对微服务的一个理解(2)服务注册与服务发现(注册中心的使用)(3)rpc协议,即服务间的调用(4)MQ的应用(5)ORM框架(6)ES 总的来说就是两点对微服务的理解和一些中间件的使用.只是简单的实现了一些功能学习下微服务的思想,而对于系统的高可用并没有做过多的认识. 在系统中大量的使用了同步调用的思想,例如创建用户时同步的调用mysql和ES.并没有考虑数据的一致性问题.对业务的侵入性太强了. 且文件服务只是简单的使用原生的文件操作进行一个处理,对于可用性方面做的很少。 在系统架构上只是对业务进行了垂直拆分,各服务还是使用的单点,各服务之间还是连接的同一个数据库。网关方面也只是简单做一个身份识别,这种架构其实更接近与垂直架构。 # 相关文档 [IM项目-语音识别子服务](https://blog.csdn.net/2301_77412625/article/details/142362206) [IM项目-文件管理子服务](https://blog.csdn.net/2301_77412625/article/details/142364831) [IM项目-用户子服务](https://editor.csdn.net/md/?articleId=142403157) [IM项目-消息转发子服务](https://blog.csdn.net/2301_77412625/article/details/142436901) [IM项目-消息存储子服务](https://blog.csdn.net/2301_77412625/article/details/142444195) [IM项目-好友子服务](https://blog.csdn.net/2301_77412625/article/details/142544193) [IM项目-网关子服务](https://blog.csdn.net/2301_77412625/article/details/142611069) [IM项目-项目部署](https://blog.csdn.net/2301_77412625/article/details/142613460)