# Netty_FlashMan **Repository Path**: vxinv/Netty_FlashMan ## Basic Information - **Project Name**: Netty_FlashMan - **Description**: 闪电侠的掘金小册 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 5 - **Created**: 2021-03-29 - **Last Updated**: 2024-05-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 仿微信 IM 系统简介 > 微信从 2011 年 1 月 21 日诞生至今,已经成为国内数亿用户必不可少的即时通信工具,是男女老少手机中必备的顶级 App。Netty 是一个异步基于事件驱动的高性能网络通信框架,在互联网中间件领域网络通信层是无可争议的最强王者,两者强强联合又会擦出什么样的火花?在接下来的小节中,我将带领大家使用 Netty 一步一步实现微信 IM 聊天的核心功能。 微信的聊天又分为单聊和群聊,下面分别来介绍一下。 ## 单聊流程 单聊指的是两个用户之间相互聊天。下面我们来看一下,用户单聊的基本流程 ![单聊流程](https://user-gold-cdn.xitu.io/2018/8/9/1651c08e91cdd8e6?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) 1. 如上图,A 要和 B 聊天,首先 A 和 B 需要与服务器建立连接,然后进行一次登录流程,服务端保存用户标识和 TCP 连接的映射关系 2. A 发消息给 B,首先需要将带有 B 标识的消息数据包发送到服务器,然后服务器从消息数据包中拿到 B 的标识,找到对应的 B 的连接,将消息发送给 B 3. 任意一方发消息给对方,如果对方不在线,需要将消息缓存,对方上线之后再发送 我们把客户端与服务端之间相互通信的数据包称为**指令数据包**,指令数据包分为指令和数据,每一种指令对应客户端或者服务端的一种操作,数据部分对应的是指令处理需要的数据。 下面我们先来看一下,要实现单聊,客户端与服务端分别要实现哪些指令: ## 单聊的指令 ### 指令图示 ![image.png](https://user-gold-cdn.xitu.io/2018/9/24/1660adaac93d16e2?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) ### 指令列表 | 指令内容 | 客户端 | 服务端 | | :----------: | :----: | :----: | | 登录请求 | 发送 | 接收 | | 登录响应 | 接收 | 发送 | | 客户端发消息 | 发送 | 接收 | | 服务端发消息 | 接收 | 发送 | | 登出请求 | 发送 | 接收 | | 登出响应 | 接收 | 发送 | ## 群聊流程 群聊指的是一个组内多个用户之间的聊天,一个用户发到群组的消息会被组内任何一个成员接收,下面我们来看一下群聊的基本流程 ![image.png](https://user-gold-cdn.xitu.io/2018/8/9/1651c08e91bfb935?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) 如上图,要实现群聊,其实和单聊类似 1. A,B,C 依然会经历登录流程,服务端保存用户标识对应的 TCP 连接 2. A 发起群聊的时候,将 A,B,C 的标识发送至服务端,服务端拿到之后建立一个群聊 ID,然后把这个 ID 与 A,B,C 的标识绑定 3. 群聊里面任意一方在群里聊天的时候,将群聊 ID 发送至服务端,服务端拿到群聊 ID 之后,取出对应的用户标识,遍历用户标识对应的 TCP 连接,就可以将消息发送至每一个群聊成员 下面,我们再来看一下群聊除了需要实现上述指令之外,还需要实现的指令集 ## 群聊要实现的指令集 ### 指令图示 ![image.png](https://user-gold-cdn.xitu.io/2018/9/24/1660ae0860e0cf88?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) ### 指令列表 | 指令内容 | 客户端 | 服务端 | | :--------------: | :----: | :----: | | 创建群聊请求 | 发送 | 接收 | | 群聊创建成功通知 | 接收 | 发送 | | 加入群聊请求 | 发送 | 接收 | | 群聊加入通知 | 接收 | 发送 | | 发送群聊消息 | 发送 | 接收 | | 接收群聊消息 | 接收 | 发送 | | 退出群聊请求 | 发送 | 接收 | | 退出群聊通知 | 接收 | 发送 | ## Netty 我们使用 Netty 统一的 IO 读写 API 以及强大的 pipeline 来编写业务处理逻辑,在后续的章节中,我会通过 IM 这个例子,带你逐步了解 Netty 的以下核心知识点。 - 服务端如何启动 - 客户端如何启动 - 数据载体 ByteBuf - 长连自定义协议如何设计 - 粘包拆包原理与实践 - 如何实现自定义编解码 - pipeline 与 channelHandler - 定时发心跳怎么做 - 如何进行连接空闲检测 ### 客户端使用 Netty 的程序逻辑结构 ![image.png](https://user-gold-cdn.xitu.io/2018/8/9/1651c08e91ca8b74?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) 上面这幅图展示了客户端的程序逻辑结构 1. 首先,客户端会解析控制台指令,比如发送消息或者建立群聊等指令 2. 然后,客户端会基于控制台的输入创建一个指令对象,用户告诉服务端具体要干什么事情 3. TCP 通信需要的数据格式为二进制,因此,接下来通过自定义二进制协议将指令对象封装成二进制,这一步称为协议的编码 4. 对于收到服务端的数据,首先需要截取出一段完整的二进制数据包(拆包粘包相关的内容后续小节会讲解) 5. 将此二进制数据包解析成指令对象,比如收到消息 6. 将指令对象送到对应的逻辑处理器来处理 ### 服务端使用 Netty 的程序逻辑结构 ![image.png](https://user-gold-cdn.xitu.io/2018/8/21/1655969de0f3b8c8?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) 服务端的程序逻辑结构与客户端非常类似,这里不太赘述。 ## 本小册实现 IM 的形式 由于本小册以传授 Netty 基础知识为主,故 IM 相关的图形化界面不会涉及,后续所有的聊天基于控制台进行,通过与控制台交互可以进行单聊和群聊。