0
点赞
收藏
分享

微信扫一扫

IM登录服务器和消息服务器设计

奋斗De奶爸 2022-02-19 阅读 57

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

2 IM登录服务器和消息服务器设计

1. 通信协议设计

2. reactor模型

3. login_server分析

4. 数据库设计

5. 登录业务分析

6. msg_server分析

0 源码分布

0voice_im\server\src
◼ base基础组件
在这里插入图片描述

1. 1 通信协议设计-格式

在这里插入图片描述

1. 2 通信协议设计-protobuf

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

1.3 通信协议设计-结构体

typedef struct {
	uint32_t length; // the whole pdu length 代表这个包
	uint16_t version; // pdu version number
	uint16_t flag; // not used
	uint16_t service_id; //
	uint16_t command_id; //
	uint16_t seq_num; // 包序号
	uint16_t reversed; // 保留
} PduHeader_t;
Header + body

1.4 通信协议设计-包完整性判断 1

在这里插入图片描述

1. Socket TCP(可靠性)
2. 协议设计的边界处理 header + body,通过header的

length字段( 4 字节)解决
3. Service ID和Command ID区分不同的命令
4. TCP粘包问题通过缓存解决数据

1.4 通信协议设计-包完整性判断 2

CImPdu::ReadPdu
CImConn::OnRead

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2 login_server分析

login_server

这个服务是用来做负载均
衡的

在这里插入图片描述

3.1 reactor模型-CBaseSocket

在这里插入图片描述

socket自定义状态:
SOCKET_STATE_IDLE :CBaseSocket()
SOCKET_STATE_LISTENING:Listen() 作为server的时候用
SOCKET_STATE_CONNECTING :Connect() 作为client的时候用
SOCKET_STATE_CONNECTED: OnWrite() 作为client的时候用
SOCKET_STATE_CLOSING: OnClose()
CBaseSocket:管理socket io,作为client或者server都需要实例化一个CBaseSocket
hash_map<net_handle_t, CBaseSocket*> SocketMap; 管理所有的连接,以fd为key,
CBaseSocket对象为value,对应处理:
  1. void AddBaseSocket(CBaseSocket* pSocket) 增
  2. void RemoveBaseSocket(CBaseSocket* pSocket) 删
  3. CBaseSocket* FindBaseSocket(net_handle_tfd) 查

3.2 reactor模型-CEventDispatch

CEventDispatch是reactor的触发器,epoll相关的函数都在此调用。
Timer相关
AddTimer:加入定时事件
RemoveTimer:删除定时事件
_CheckTimer:检测定时事件
Loop相关
AddLoop:加入循环事件
_CheckLoop:检测循环事件
epoll相关
AddEvent: 添加fd事件
RemoveEvent:删除fd事件
StartDispatch:进入reactor主循环
StopDispatch:停止reactor主循环

3.3 reactor模型-api netlib

在这里插入图片描述

CEventDispatch是reactor的触发器,但不是对外的api,netlib是对外的api。
fd相关
◼ netlib_listen:监听
◼ netlib_connect:连接
◼ netlib_send:发送
◼ netlib_recv:接收
◼ netlib_close:关闭
◼ netlib_option:参数设置
◼ NETLIB_OPT_SET_CALLBACK设置回调函数
定时器相关
◼ netlib_register_timer:注册定时器
◼ netlib_delete_timer:删除定时器
循环相关
◼ netlib_add_loop:可以加入需要循环处理的事务到reactor
◼ netlib_eventloop:进入reactor主循环

3.4 reactor模型-http服务和IM协议的区别

在这里插入图片描述在这里插入图片描述

Listen 设置回调
netlib_option:NETLIB_OPT_SET_CALLBACK 设置回调函数

login_server.cpp

4 数据库设计

在这里插入图片描述

5.1 登录业务

登录账号验证与状态同步
◼ 用户名密码校验
◼ 在线状态设置+路由状态更新
◼ 旧客户端账号下线
◼ 通知好友,移动时代, 24 小时在校
登录数据准备
◼ 分组信息
◼ 好友列表
◼ 群组列表
◼ 好友信息
◼ 未读消息
◼ 其他…

5.1 登录业务-续 1

登录账号验证与状态同步
◼ 用户名密码校验

在这里插入图片描述

◼ 在线状态设置+路由状态更新

在这里插入图片描述

 客户端状态
 服务端状态
 路由状态更新
明文密码不能用
客户端 md5(password)

5.1 登录业务-续 2 旧客户端账号下线

登录账号验证与状态同步
◼ 如果账号已经登录,则将其强迫下线

在这里插入图片描述

  1. 办公室pc登录
    ( 1 )手机再登录没有问题
    ( 2 )如果在家里的pc登录,办公室下线

2 手机登录
( 1 )换个手机再登录,之前的手机下线
(2 )如果使用pc登录,没有问题,提示pc有登录

根据实际需求提供策略。

5.1 登录业务-续 3 通知好友

在这里插入图片描述

登录账号验证与状态同步
◼ 通知好友

5.1 登录业务-续 4 同步信息

同步信息
◼ 好友列表
◼ 分组列表
◼ 群组列表
◼ 未读消息
特别是登录微信
特别是换了新手机,登录过程特别慢。
作业:是不是每次登录都需要全部拉取:
◼ 好友列表
◼ 分组列表
◼ 未读消息
怎么做到不全部拉取。

6.1 msg_server登录流程

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

6.2 msg_server发送消息

在这里插入图片描述

6.3 msg_server登录请求响应过程-更新信息 1在这里插入图片描述

6.3 msg_server登录请求响应过程 2

在这里插入图片描述

6.3 msg_server登录请求响应过程 3

在这里插入图片描述

框架图

在这里插入图片描述

举报

相关推荐

0 条评论