推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家: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,对应处理:
- void AddBaseSocket(CBaseSocket* pSocket) 增
- void RemoveBaseSocket(CBaseSocket* pSocket) 删
- 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 旧客户端账号下线
登录账号验证与状态同步
◼ 如果账号已经登录,则将其强迫下线
- 办公室pc登录
( 1 )手机再登录没有问题
( 2 )如果在家里的pc登录,办公室下线
2 手机登录
( 1 )换个手机再登录,之前的手机下线
(2 )如果使用pc登录,没有问题,提示pc有登录
根据实际需求提供策略。
5.1 登录业务-续 3 通知好友
登录账号验证与状态同步
◼ 通知好友
5.1 登录业务-续 4 同步信息
同步信息
◼ 好友列表
◼ 分组列表
◼ 群组列表
◼ 未读消息
特别是登录微信
特别是换了新手机,登录过程特别慢。
作业:是不是每次登录都需要全部拉取:
◼ 好友列表
◼ 分组列表
◼ 未读消息
怎么做到不全部拉取。
6.1 msg_server登录流程