冰河技术
导读
♻学习路线
  • 面试必问系列

    • 面试必问
  • 架构与模式

    • Java极简设计模式
    • 实战高并发设计模式
  • Java核心技术

    • Java8新特性
    • IOC核心技术
    • JVM调优技术
  • 容器化核心技术

    • Dockek核心技术
  • 分布式存储

    • Mycat核心技术
  • 数据库核心技术

    • MySQL基础篇
  • 服务器核心技术

    • Nginx核心技术
  • 渗透核心技术

    • 渗透实战技术
  • 底层技术
  • 源码分析
  • 基础案例
  • 实战案例
  • 面试
  • 系统架构
  • Spring6核心技术
  • 分布式事务

    • 分布式事务系列视频
  • SpringBoot
  • SpringCloudAlibaba
  • 🔥AI大模型项目

    • 一站式AI智能平台
    • AI智能客服系统
    • AI智能问答系统
    • 实战AI大模型
  • 中间件项目

    • 手写高性能Redis组件
    • 手写高性能脱敏组件
    • 手写线程池项目
    • 手写高性能SQL引擎
    • 手写高性能Polaris网关
    • 手写高性能RPC项目
  • 高并发项目

    • 分布式IM即时通讯系统(新)
    • 分布式Seckill秒杀系统
    • 实战高并发设计模式
  • 微服务项目

    • 简易电商脚手架项目
  • 手撕源码

    • 手撕Spring6源码
🌍知识星球
  • 总览

    • 《书籍汇总》
  • 出版图书

    • 《深入理解高并发编程:核心原理与案例实战》
    • 《深入理解高并发编程:JDK核心技术》
    • 《深入高平行開發:深度原理&專案實戰》
    • 《深入理解分布式事务:原理与实战》
    • 《MySQL技术大全:开发、优化与运维实战》
    • 《海量数据处理与大数据技术实战》
  • 电子书籍

    • 《实战高并发设计模式》
    • 《深入理解高并发编程(第2版)》
    • 《深入理解高并发编程(第1版)》
    • 《从零开始手写RPC框架(基础篇)》
    • 《SpringCloud Alibaba实战》
    • 《冰河的渗透实战笔记》
    • 《MySQL核心知识手册》
    • 《Spring IOC核心技术》
  • 关于自己
  • 关于学习
  • 关于职场
B站
Github
导读
♻学习路线
  • 面试必问系列

    • 面试必问
  • 架构与模式

    • Java极简设计模式
    • 实战高并发设计模式
  • Java核心技术

    • Java8新特性
    • IOC核心技术
    • JVM调优技术
  • 容器化核心技术

    • Dockek核心技术
  • 分布式存储

    • Mycat核心技术
  • 数据库核心技术

    • MySQL基础篇
  • 服务器核心技术

    • Nginx核心技术
  • 渗透核心技术

    • 渗透实战技术
  • 底层技术
  • 源码分析
  • 基础案例
  • 实战案例
  • 面试
  • 系统架构
  • Spring6核心技术
  • 分布式事务

    • 分布式事务系列视频
  • SpringBoot
  • SpringCloudAlibaba
  • 🔥AI大模型项目

    • 一站式AI智能平台
    • AI智能客服系统
    • AI智能问答系统
    • 实战AI大模型
  • 中间件项目

    • 手写高性能Redis组件
    • 手写高性能脱敏组件
    • 手写线程池项目
    • 手写高性能SQL引擎
    • 手写高性能Polaris网关
    • 手写高性能RPC项目
  • 高并发项目

    • 分布式IM即时通讯系统(新)
    • 分布式Seckill秒杀系统
    • 实战高并发设计模式
  • 微服务项目

    • 简易电商脚手架项目
  • 手撕源码

    • 手撕Spring6源码
🌍知识星球
  • 总览

    • 《书籍汇总》
  • 出版图书

    • 《深入理解高并发编程:核心原理与案例实战》
    • 《深入理解高并发编程:JDK核心技术》
    • 《深入高平行開發:深度原理&專案實戰》
    • 《深入理解分布式事务:原理与实战》
    • 《MySQL技术大全:开发、优化与运维实战》
    • 《海量数据处理与大数据技术实战》
  • 电子书籍

    • 《实战高并发设计模式》
    • 《深入理解高并发编程(第2版)》
    • 《深入理解高并发编程(第1版)》
    • 《从零开始手写RPC框架(基础篇)》
    • 《SpringCloud Alibaba实战》
    • 《冰河的渗透实战笔记》
    • 《MySQL核心知识手册》
    • 《Spring IOC核心技术》
  • 关于自己
  • 关于学习
  • 关于职场
B站
Github
  • 开篇:专栏介绍

    • 开篇:分布式IM即时通讯系统正式启动
    • 面试:可以写到简历上的分布式IM即时通讯系统
  • 第01部分:需求设计

    • 第01节:为何要学习分布式IM即时通讯系统
    • 第02节:分布式IM即时通讯系统的目标与挑战
    • 第03节:分布式IM即时通讯系统功能需求与流程梳理
    • 第04节:分布式IM即时通讯系统技术流程梳理
  • 第02部分:总体架构设计

    • 第01节:分布式IM即时通讯系统总体方案目标与架构设计
    • 第02节:分布式IM即时通讯系统数据模型设计
  • 第03部分:环境搭建

    • 第01节:分布式IM即时通讯系统研发环境搭建
    • 第02节:分布式IM即时通讯系统项目工程搭建
    • 第03节:分布式IM即时通讯系统Maven私服搭建
    • 第04节:搭建并优化多节点Minio分布式文件系统
  • 第04部分:通用模型设计

    • 第01节:分布式IM即时通讯系统通用模型设计
    • 第02节:分布式IM即时通讯系统通用缓存设计
    • 第03节:混合型缓存通用模型设计与实现
    • 第04节:分布式锁通用代码设计与实现
    • 第05节:MQ消息发送通用代码设计与实现
    • 第06节:多系统共用模型与工具推送到Maven私服
    • 第07节:分布式ID生成器的设计与实现
  • 第05部分:即时通讯后端服务

    • 第01节:通用代码设计与实现
    • 第02节:自定义编解码器的设计与实现
    • 第03节:通用ChannelHanler的设计与实现
    • 第04节:登录处理器的设计与实现
    • 第05节:心跳处理器的设计与实现
    • 第06节:单聊处理器的设计与实现
    • 第07节:群聊处理器的设计与实现
  • 第06部分:即时通讯SDK

    • 第01节:发送单聊消息的流程设计与实现
    • 第02节:发送群聊消息的流程设计与实现
    • 第03节:在线状态的统一设计与实现
    • 第04节:消息监听与广播机制的设计与实现
    • 第05节:接收消息发送结果的流程设计与实现
  • 第07部分:大后端平台-通用模型

    • 第01节:领域层对象模型的设计与实现
    • 第02节:用户Session与全局异常捕获机制
    • 第03节:缓存参数过滤器的设计与实现
    • 第04节:通用拦截器规则链的设计和实现
    • 第05节:XSS漏洞校验规则的设计和实现
    • 第06节:滑动窗口IP校验规则的设计和实现
    • 第07节:资源访问校验规则的设计和实现
    • 第08节:账号安全校验规则的设计和实现
  • 第08部分:大后端平台-用户微服务

    • 第01节:用户注册与登录授权的流程设计与实现
    • 第02节:JWT Token刷新机制的流程设计与实现
    • 第03节:用户微服务常规功能的设计与实现
    • 第04节:用户微服务整合即时通讯SDK
    • 第05节:领域事件的发送与接收设计和实现
    • 第06节:用户微服务整合Dubbo的流程设计与实现
  • 第09部分:大后端平台-好友微服务

    • 第01节:好友服务常规功能的设计和实现
    • 第02节:好友微服务整合Dubbo的流程设计与实现
    • 第03节:领域事件的发送与接收设计和实现
    • 第04节:异步更新好友微服务数据的设计和实现
  • 第10部分:大后端平台-群组微服务

    • 第01节:群组微服务常规功能的设计和实现
    • 第02节:群组微服务整合Dubbo的流程设计和实现
    • 第03节:业务事件的发送与接收设计和实现
    • 第04节:异步更新群组微服务数据的设计和实现
  • 第11部分:大后端平台-消息微服务

    • 第01节:单聊消息的发送流程设计和实现
    • 第02节:群聊消息的发送流程设计和实现
    • 第03节:单聊消息的拉取流程设计和实现
    • 第04节:群聊消息的拉取流程设计和实现
    • 第05节:单聊消息的已读流程设计和实现
    • 第06节:群聊消息的已读流程设计和实现
    • 第07节:单聊消息的撤回流程设计和实现
    • 第08节:群聊消息的撤回流程设计和实现
    • 第09节:图片、文件和语音消息的设计和实现
    • 第10节:消息监听回调流程的设计和实现
  • 第12部分:大后端平台-视频通话

    • 第01节:视频通话呼叫发起流程设计和实现
    • 第02节:视频通话呼叫取消流程设计和实现
    • 第03节:视频通话呼叫失败流程设计和实现
    • 第04节:视频通话呼叫接受流程设计和实现
    • 第05节:视频通话呼叫拒绝流程设计和实现
    • 第06节:视频通话呼叫挂断流程设计和实现
    • 第07节:视频通话同步会话状态流程设计和实现
  • 第13部分:大前端UI-基础架构

    • 第01节:Node.js基础环境搭建
    • 第02节:通用基础功能设计与研发
  • 第14部分:大前端UI-用户模块

    • 第01节:注册与登录流程的设计与实现
    • 第02节:页面主体框架设计与实现
  • 第15部分:大前端UI-好友模块

    • 第01节:好友主体页面的设计与实现
    • 第02节:好友关联单聊页面的设计与实现
  • 第16部分:大前端UI-群组模块

    • 第01节:群组主体页面的设计与实现
    • 第02节:创建群组流程的设计与实现
    • 第03节:修改群组流程的设计与实现
    • 第04节:邀请好友进群流程的设计与实现
    • 第05节:群主踢人出群流程的设计与实现
    • 第06节:成员退出群组流程的设计与实现
    • 第07节:群主解散群组流程的设计与实现
    • 第08节:发送群聊消息流程的设计与实现
  • 第17部分:大前端UI-消息模块

    • 第01节:发送文字消息流程的设计与实现
    • 第02节:发送表情消息流程的设计与实现
    • 第03节:发送图片消息流程的设计与实现
    • 第04节:发送文件消息流程的设计与实现
    • 第05节:发送语音消息流程的设计与实现
    • 第06节:双向视频通话流程的设计与实现
    • 第07节:查看历史消息流程的设计与实现
    • 第08节:消息已读未读流程的设计与实现
    • 第09节:实时消息删除流程的设计与实现
    • 第10节:实时消息撤回流程的设计与实现
    • 第11节:群聊@功能流程的设计与实现
  • 第18部分:OpenAI大模型接入服务

    • 第01节:OpenAI总体对接流程架构设计
    • 第02节:OpenAI接入服务总体框架设计
    • 第03节:OpenAI领域模型与核心接口设计
    • 第04节:OpenAI大模型对接设计和实现
    • 第05节:单聊消息对接OpenAI大模型
    • 第06节:群聊消息对接OpenAI大模型
    • 第07节:扩展实现对接多种OpenAI大模型
  • 第19部分:专栏总结

    • 总结:分布式IM即时通讯系统整体专栏总结

《分布式IM系统》即时通讯后端服务-第03节:即时通讯后端服务通用ChannelHanler的设计与实现

作者:冰河
星球:http://m6z.cn/6aeFbs
博客:https://binghe.site
文章汇总:https://binghe.site/md/all/all.html
源码获取地址:https://t.zsxq.com/0dhvFs5oR
课程视频:https://t.zsxq.com/15cCvfYNv

沉淀,成长,突破,帮助他人,成就自我。

  • 本节难度:★★☆☆☆
  • 本节重点:对即时通讯后端服务的通用数据收发ChannelHandler进行设计和实现,掌握Netty中ChannelPipeline的内部结构、事件传播机制、异常传播机制,并能够将ChannelHandler的设计和实现灵活应用到自身实际项目中。
  • 课程视频:https://t.zsxq.com/15cCvfYNv

大家好,我是冰河~~

Netty的性能是非常高的,很多通信框架底层都使用了Netty,像Dubbo框架底层网络通信就使用了Netty,我们在《RPC手撸专栏》中,自己手写的RPC框架底层网络通信也使用了Netty。Netty性能非常高,主要体现在IO线程模型、内存零拷贝、内存池设计、串形化处理读写、高性能序列化协议等方面。

一、前言

在前面的章节中,我们已经完成即时通讯后端服务的通用代码设计和实现,并对自定义的编解码器进行了设计和实现。期间,不仅介绍了如何基于Netty自定义编解码器,还介绍了自定义通信协议,Netty中的编码器类和解码器类,让大家对Netty本身提供的编解码器类有个直观的认识。本节,就需要对收发数据的ChannelHandler进行设计和实现。

二、本节诉求

本节,对Netty中ChannelPipeline的内部结构、事件传播机制、异常传播机制进行简单的介绍,旨在让大家从整体上了解Netty内部的流水线模式,基于流水线模式实现的事件传播机制和异常传播机制。在此基于上实现自定义的数据收发逻辑。

一、ChannelPipeline的内部结构

ChannelPipeline主要是基于流水线模式实现的一个Netty的的编排组件,负责调度Netty中的各种ChannelHandler,对数据的实际处理还是由ChannelHandler完成。ChannelPipeline内部通过双向链表将不同的ChannelHandler整合在一起,如果有Channel请求到来,ChannelPipeline会依次调用链表中的ChannelHandler来处理数据。如图3-1所示。


可以看到,每个Channel会绑定一个ChannelPipeline,每个ChannelPipeline内部会有多个ChannelHandlerContext,所有的ChannelHandlerContext会由一个链表进行连接。

根据数据在Netty中的流向,ChannelPipeline会分为入站ChannelInboundHandler和出站 ChannelOutboundHandler两种处理器。如果数据是由客户端向服务端发送,就叫做出站,如果是由服务端向客户端发送数据,就叫做入站。入站操作是由InboundHandler处理,而出站操作是由OutboundHandler处理。并且入站是需要经过Decoder解码器处理,而出站是由Encoder编码器处理。

HeadContext 既是 Inbound 处理器,也是 Outbound 处理器。它分别实现了 ChannelInboundHandler和ChannelOutboundHandler,整个写数据的入口就是由HeadContext完成的,HeadContext是ChannelInboundHandler调用链的第一步,也是ChannelOutboundHandler调用链的最后一步,当HeadContext接收到数据后,经过ChannelPipeline中各个ChannelHandler的处理后,最终又会由HeadContext向外写数据。

TailContext 只实现了ChannelInboundHandler 接口,它是ChannelInboundHandler调用链的最后异步,会终止InboundHandler的事件,并且TailContext 是ChannelOutboundHandler调用链的第一步,会将事件传递给上一个节点。

二、事件传播机制

Netty的ChannelPipeline中包含的处理器可以分为ChannelInboundHandler入站处理器和ChannelOutboundHandler出站处理器。对应的时间也会分成入站(Inbound)事件和出站(Outbound)事件。

这里,我们写几个基于Netty的代码片段来介绍Netty的事件传播机制。

  • 入站(Inbound)事件示例
public class InBoundHandlerExample extends ChannelInboundHandlerAdapter {
    private final String name;
    private final boolean flush;
    public InBoundHandlerExample(String name, boolean flush) {
        this.name = name;
        this.flush = flush;
    }
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (flush) {
            ctx.channel().writeAndFlush(msg);
        } else {
            super.channelRead(ctx, msg);
        }
    }
}
  • 出站(Outbound)事件示例
public class OutBoundHandlerExample extends ChannelOutboundHandlerAdapter {
    private final String ;
    public OutBoundHandlerExample(String name) {
        this.name = name;
    }

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception 
        super.write(ctx, msg, promise);
    }
}
  • 整合pipeline示例
serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
    @Override
    public void initChannel(SocketChannel ch) {
        ch.pipeline()
                .addLast(new InBoundHandlerExample("InBoundHandlerA", false))
                .addLast(new InBoundHandlerExample("InBoundHandlerB", false))
                .addLast(new InBoundHandlerExample("InBoundHandlerC", true));
        ch.pipeline()
                .addLast(new OutBoundHandlerExample("OutBoundHandlerA"))
                .addLast(new OutBoundHandlerExample("OutBoundHandlerB"))
                .addLast(new OutBoundHandlerExample("OutBoundHandlerC"));
    }
}

相信这些代码小伙伴们都能看懂,那我们就基于这些代码介绍下Netty的事件传播机制。

在上述代码片段中,我们通过Netty的pipeline的addLast()方法分别添加了三个ChannelInboundHandler处理器和三个ChannelOutboundHandler处理器,添加后的事件处理器在ChannelPipeline内的结构如图3-2所示。

查看全文

加入冰河技术知识星球,解锁完整技术文章与完整代码

在 GitHub 上编辑此页
上次更新: 2026/4/29 16:18
Contributors: binghe001
Prev
第02节:自定义编解码器的设计与实现
Next
第04节:登录处理器的设计与实现
阅读全文
×

扫码或搜索:冰河技术
发送:290992
即可立即永久解锁本站全部文章

星球会员
跳转链接