01 即时通讯系统简介

01 即时通讯系统简介

微信从 2011 年 1 月 21 日诞生至今,已经成为国内数亿用户必不可少的即时通信工具,是男女老少手机中必备的顶级 App。Netty 是一个异步基于事件驱动的高性能网络通信框架,在互联网中间件领域网络通信层是无可争议的最强王者,两者强强联合又会擦出什么样的火花?在接下来的小节中,我将带领大家使用 Netty 一步一步实现微信 IM 聊天的核心功能。

微信的聊天又分为单聊和群聊,下面分别来介绍一下。

单聊流程

单聊指的是两个用户之间相互聊天。下面我们来看一下,用户单聊的基本流程

  1. 如上图,A 要和 B 聊天,首先 A 和 B 需要与服务器建立连接,然后进行一次登录流程,服务端保存用户标识和 TCP 连接的映射关系
  2. A 发消息给 B,首先需要将带有 B 标识的消息数据包发送到服务器,然后服务器从消息数据包中拿到 B 的标识,找到对应的 B 的连接,将消息发送给 B
  3. 任意一方发消息给对方,如果对方不在线,需要将消息缓存,对方上线之后再发送

我们把客户端与服务端之间相互通信的数据包称为指令数据包,指令数据包分为指令和数据,每一种指令对应客户端或者服务端的一种操作,数据部分对应的是指令处理需要的数据。

下面我们先来看一下,要实现单聊,客户端与服务端分别要实现哪些指令:

单聊的指令

指令图示

指令列表

指令内容客户端服务端
登录请求发送接收
登录响应接收发送
客户端发消息发送接收
服务端发消息接收发送
登出请求发送接收
登出响应接收发送

群聊流程

群聊指的是一个组内多个用户之间的聊天,一个用户发到群组的消息会被组内任何一个成员接收,下面我们来看一下群聊的基本流程

如上图,要实现群聊,其实和单聊类似

  1. A,B,C 依然会经历登录流程,服务端保存用户标识对应的 TCP 连接
  2. A 发起群聊的时候,将 A,B,C 的标识发送至服务端,服务端拿到之后建立一个群聊 ID,然后把这个 ID 与 A,B,C 的标识绑定
  3. 群聊里面任意一方在群里聊天的时候,将群聊 ID 发送至服务端,服务端拿到群聊 ID 之后,取出对应的用户标识,遍历用户标识对应的 TCP 连接,就可以将消息发送至每一个群聊成员

下面,我们再来看一下群聊除了需要实现上述指令之外,还需要实现的指令集

群聊要实现的指令集

指令图示

指令列表

指令内容客户端服务端
创建群聊请求发送接收
群聊创建成功通知接收发送
加入群聊请求发送接收
群聊加入通知接收发送
发送群聊消息发送接收
接收群聊消息接收发送
退出群聊请求发送接收
退出群聊通知接收发送

Netty

我们使用 Netty 统一的 IO 读写 API 以及强大的 pipeline 来编写业务处理逻辑,在后续的章节中,我会通过 IM 这个例子,带你逐步了解 Netty 的以下核心知识点。

  • 服务端如何启动
  • 客户端如何启动
  • 数据载体 ByteBuf
  • 长连自定义协议如何设计
  • 粘包拆包原理与实践
  • 如何实现自定义编解码
  • pipeline 与 channelHandler
  • 定时发心跳怎么做
  • 如何进行连接空闲检测

客户端使用 Netty 的程序逻辑结构

上面这幅图展示了客户端的程序逻辑结构

  1. 首先,客户端会解析控制台指令,比如发送消息或者建立群聊等指令
  2. 然后,客户端会基于控制台的输入创建一个指令对象,用户告诉服务端具体要干什么事情
  3. TCP 通信需要的数据格式为二进制,因此,接下来通过自定义二进制协议将指令对象封装成二进制,这一步称为协议的编码
  4. 对于收到服务端的数据,首先需要截取出一段完整的二进制数据包(拆包粘包相关的内容后续小节会讲解)
  5. 将此二进制数据包解析成指令对象,比如收到消息
  6. 将指令对象送到对应的逻辑处理器来处理

服务端使用 Netty 的程序逻辑结构

服务端的程序逻辑结构与客户端非常类似,这里不太赘述。


已有 0 条评论

    欢迎您,新朋友,感谢参与互动!