聊天室项目入口网关子服务的实现

设计思想

入口网关子服务是整个聊天室唯一面向客户端的服务 ,不对外提供任何业务逻辑,只承担三件事:HTTP 接入与分发、登录会话鉴权、WebSocket 长连接推送。服务启动时先构造 Redis 客户端(承载登录会话与在线状态),再以服务根目录为监控范围创建服务发现客户端,把文件存储、语音识别、消息存储、好友管理、用户管理、消息转发六个子服务 全部登记为管理目标,并注册服务上线与服务下线回调------子服务实例上下线时自动增删对应信道,调用时从当前可用节点中轮转选择;随后创建 HTTP 服务器与 WebSocket 服务器,把 30 个业务接口按路径逐一注册为 HTTP POST 处理函数,并监听对应的 HTTP 端口与 WebSocket 端口。网关自身不注册到注册中心 ------它只消费注册中心里的服务信息。运行期有两条链路:HTTP 链路 上,客户端一律以 POST 方式提交 protobuf 二进制正文,网关先反序列化、再从 Redis 中校验登录会话取出用户身份(注册、登录、验证码三类接口免鉴权),随后从信道管理中选出对应子服务的节点发起 brpc 调用,把子服务的响应序列化后回写为 HTTP 响应;WebSocket 链路上,客户端连接建立后发送首帧身份识别信息,网关反序列化出登录会话 ID 并到 Redis 中查证,查不到则直接关闭连接,查到则把该连接登记进长连接管理(维护用户 ID 与连接的映射),此后由网关按子服务返回的目标用户 ID 找到对应连接并推送通知------好友申请、申请处理结果、好友删除、会话建立与新消息五类通知皆由此发出。连接断开时,网关从 Redis 中删除该会话与在线状态,并从长连接管理中移除连接。

功能设计

网关服务器在设计中,最重要的两个功能:

  • 作为入口服务器接收客户端的所有请求,进行请求的子服务分发,得到响应后进行响应
  • 对客户端进行事件通知(好友申请和处理及删除,单聊 / 群聊会话创建,新消息)

基于以上的两个功能,因此网关服务器包含两项通信:

  • HTTP 通信:进行业务处理
  • WEBSOCKET 通信:进行事件通知

模块划分:

  1. 参数 / 配置文件解析模块:基于 gflags 框架直接使用进行参数 / 配置文件解析。
  2. 日志模块:基于 spdlog 框架封装的模块直接使用进行日志输出。
  3. rpc 服务发现与调用模块:基于 etcd 框架与 brpc 框架封装的服务发现与调用模块 a. 因为要分发处理所有请求,因此所有的子服务都需要进行服务发现。
  4. redis 客户端模块:基于 redis++ 封装的客户端端进行内存数据库数据操作 a. 根据用户子服务添加的会话信息进行用户连接身份识别与鉴权
  5. HTTP 通信服务器模块:基于 cpp-httplib 库搭建 HTTP 服务器,接收 HTTP 请求进行业务处理。
  6. WEBSOCKET 服务器模块:基于 Websocketpp 库,搭建 websocket 服务器,进行事件通知。
  7. 客户端长连接管理模块:建议用户 ID 与长连接句柄映射关系,便于后续根据用户 ID 找到连接进行事件通知

接口实现流程:

用户名注册

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 查找用户子服务
  3. 调用子服务对应接口进行业务处理
  4. 将处理结果响应给客户端。

用户名登录

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 查找用户子服务
  3. 调用子服务对应接口进行业务处理
  4. 将处理结果响应给客户端。

短信验证码获取

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 查找用户子服务
  3. 调用子服务对应接口进行业务处理
  4. 将处理结果响应给客户端。

手机号码注册

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 查找用户子服务
  3. 调用子服务对应接口进行业务处理
  4. 将处理结果响应给客户端。

手机号码登录

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 查找用户子服务
  3. 调用子服务对应接口进行业务处理
  4. 将处理结果响应给客户端。

用户信息获取

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找用户子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

修改用户头像

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找用户子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

修改用户签名

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找用户子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

修改用户昵称

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找用户子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

修改用户绑定手机号

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找用户子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

获取好友列表

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找好友子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

发送好友申请

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找用户子服务
  4. 根据请求中的用户 ID,调用用户子服务,获取用户的详细信息
  5. 查找好友子服务
  6. 调用子服务对应接口进行业务处理
  7. 若处理成功,则通过被申请人 ID,查找对方长连接 a. 若长连接存在(对方在线),则组织好友申请通知进行事件通知
  8. 将处理结果响应给客户端。

获取待处理好友申请

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找好友子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

好友申请处理

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找用户子服务
  4. 根据请求中的用户 ID,调用用户子服务,获取申请人与被申请人的详细信息
  5. 查找好友子服务
  6. 调用子服务对应接口进行业务处理
  7. 若处理成功,则通过申请人 ID,查找申请人长连接,进行申请处理结果的通知 a. 若处理结果是同意,则意味着新聊天会话的创建,则对申请人继续进行聊天会话创建通知 i. 从处理结果中取出会话 ID,使用对方的昵称作为会话名称,对方的头像作为会话头像组织会话信息 b. 若处理结果是同意,则对当前处理者用户 ID 查找长连接,进行聊天会话创建的通知 i. 从处理结果中取出会话 ID,使用对方的昵称作为会话名称,对方的头像作为会话头像组织会话信息 c. 清理响应中的会话 ID 信息
  8. 将处理结果响应给客户端

删除好友

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找好友子服务
  4. 调用子服务对应接口进行业务处理
  5. 若处理成功,则通过被删除者用户 ID,查找对方长连接 a. 若长连接存在(对方在线),则组织好友删除通知进行事件通知
  6. 将处理结果响应给客户端。

搜索用户

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找好友子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

获取用户聊天会话列表

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找好友子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

创建多人聊天会话

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找好友子服务
  4. 调用子服务对应接口进行业务处理
  5. 若处理成功,循环根据会话成员的 ID 找到他们的长连接 a. 根据响应中的会话信息,逐个进行会话创建的通知 b. 清理响应中的会话信息
  6. 将处理结果响应给客户端。

获取消息会话成员列表

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找好友子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

发送新消息

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找消息转发子服务
  4. 调用子服务对应接口进行业务处理
  5. 若处理成功,则根据处理结果中的用户 ID 列表,循环找到目标长连接,根据处理结果中的消息字段组织新消息通知,逐个对目标进行新消息通知。
  6. 若处理失败,则根据处理结果中的错误提示信息,设置响应内容
  7. 将处理结果响应给客户端。

获取指定时间段消息列表

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找消息存储子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

获取最近 N 条消息列表

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找消息存储子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

搜索关键字历史消息

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找消息存储子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

单个文件数据获取

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找文件子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

多个文件数据获取

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找文件子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

单个文件数据上传

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找文件子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

多个文件数据上传

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找文件子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。

语音转文字

  1. 取出 HTTP 请求正文,进行 ProtoBuf 反序列化
  2. 根据请求中的会话 ID 进行鉴权,并获取用户 ID,向请求中设置用户 ID
  3. 查找语音子服务
  4. 调用子服务对应接口进行业务处理
  5. 将处理结果响应给客户端。需要我把这一整段和前面【功能设计、模块划分、架构图说明】合并成一份完整报告文本吗?
相关推荐
GeW17 分钟前
深圳APEC峰会倒计时:数据库与Linux运维的"隐形考场"
linux
梦到啥说啥1 小时前
Linux网络编程:UDP网络协议
linux·网络协议·udp
无足鸟ICT3 小时前
【RHCA+】ipcrm命令(删除IPC资源)
linux
csdn_aspnet3 小时前
C++ 3个有序点的方向(Orientation of 3 ordered points)
c++·算法
星恒随风4 小时前
MySQL 从零入门(四):表的增删改查与基础查询详解
linux·服务器·数据库·笔记·mysql
小七在进步4 小时前
string的使用(2)
c++
青少儿编程课堂5 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:折半搜索优化子集枚举(Meet in the Middle)解析
c++·python·算法·bfs·信息学竞赛
陈希1237 小时前
Linux 网络诊断工具实战:ping、curl、tcpdump、mtr、dig 用法详解
linux·网络·tcpdump
wo_jack7 小时前
C++ 入门笔记(十七):list 入门 —— 为什么 list 不能 sort?
数据结构·c++·面试·stl·list