分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 软件开发

Netty源码分析第7章(编码器和写数据)---->第2节: MessageToByteEncoder

发布时间:2023-09-06 02:28责任编辑:白小东关键词:暂无标签

 

Netty源码分析第七章: Netty源码分析

 

第二节: MessageToByteEncoder

 

同解码器一样, 编码器中也有一个抽象类叫MessageToByteEncoder, 其中定义了编码器的骨架方法, 具体编码逻辑交给子类实现

解码器同样也是个handler, 将写出的数据进行截取处理, 我们在学习pipeline中我们知道, 写数据的时候会传递write事件, 传递过程中会调用handler的write方法, 所以编码器码器可以重写write方法, 将数据编码成二进制字节流然后再继续传递write事件

首先看MessageToByteEncoder的类声明:

public abstract class MessageToByteEncoder<I> extends ChannelOutboundHandlerAdapter{ ???//省略类体}

这里继承ChannelOutboundHandlerAdapter, 说明是个outBoundhandler, 我们知道write事件是个outBound事件, 而outBound事件只能通过outBoundHandler进行传输

write事件传播过程中要调用handler的write方法

我们跟到MessageToByteEncoder的write方法中:

public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { ???ByteBuf buf = null; ???try { ???????if (acceptOutboundMessage(msg)) { ???????????@SuppressWarnings("unchecked") ???????????I cast = (I) msg; ???????????buf = allocateBuffer(ctx, cast, preferDirect); ???????????try { ???????????????encode(ctx, cast, buf); ???????????} finally { ???????????????ReferenceCountUtil.release(cast); ???????????} ???????????if (buf.isReadable()) { ???????????????ctx.write(buf, promise); ???????????} else { ???????????????buf.release(); ???????????????ctx.write(Unpooled.EMPTY_BUFFER, promise); ???????????} ???????????buf = null; ???????} else { ???????????ctx.write(msg, promise); ???????} ???} catch (EncoderException e) { ???????throw e; ???} catch (Throwable e) { ???????throw new EncoderException(e); ???} finally { ???????if (buf != null) { ???????????buf.release(); ???????} ???}}

首先通过 if (acceptOutboundMessage(msg)) 判断当前对象是否可处理

如果可处理, 则进入if块中的逻辑, 如果不能处理, 则进入else块, 通过ctx.write(msg, promise)继续传递write事件

我们看if块中

 I cast = (I) msg 这里是强制类型转换, 转换成I类型, I类型是个泛型, 具体类型由用户定义

 buf = allocateBuffer(ctx, cast, preferDirect) 这里进行缓冲区分配

跟到allocateBuffer方法中:

protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, @SuppressWarnings("unused") I msg, ???????????????????????????boolean preferDirect) throws Exception { ???if (preferDirect) { ???????return ctx.alloc().ioBuffer(); ???} else { ???????return ctx.alloc().heapBuffer(); ???}}

这里会直接通过ctx的内存分配器进行内存分配, 通过判断preferDirect来分配堆内存或者堆外内存, 默认情况下是分配堆外内存

有关内存分配, 我们之前已经做过相关的剖析

回到write方法中:

内存分配结束之后会调用encode(ctx, cast, buf)方法进行编码, 该类由子类实现

子类可以通过继承该类, 重写encode方法, 将参数对象cast编码成字节写入到传入的ByteBuf中, 就完成了编码工作

编码完成后后, 会通过ReferenceCountUtil.release(cast)将cast对象释放

 if (buf.isReadable()) 这里判断buf是否有可读字节, 如果有可读字节, 则继续传递write事件

如果没有可读字节, 则将buf进行释放, 继续传播write事件, 传递一个空的ByteBuf

最后将buf设置为空

以上就是有关抽象编码器的抽象逻辑, 具体的编码逻辑还需要其子类去做

 

Netty源码分析第7章(编码器和写数据)---->第2节: MessageToByteEncoder

原文地址:https://www.cnblogs.com/xiangnan6122/p/10208131.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved