一.netty编码概述
我们发送数据时候,需要将java对象发送到网络前,需要把java对象编码成byteBuf,写入jdk底层的socket中,通过二进制数据,在网络中传输,把java对象转换为byteBuf过程就是编码
举例如下
public class MyEncode extends MessageToByteEncoder<Person> {
@Override
protected void encode(ChannelHandlerContext ctx, Person person, ByteBuf out) throws Exception {
long length = person.getLength();
out.writeShort((int) length);
out.writeBytes(person.getName().getBytes());
}
}
@Data
public class Person {
private long length;
private String name;
}
java对象Person只有简单的两个字段,第一个字段记录name的长度,第二个字段就是name的值
二.writeAndFlush步骤
在handler中发送数据,可以调用
ctx.writeAndFlush(person);
通过之前的讲解 # netty源码分析(五):pipline# 六.outboud事件传播 数据传播可以看到,会从当前handler节点往前找到outboud类型的handler,进行传播,会调用两个方法
- invokeWrite0(msg, promise);
- invokeFlush0();
1.invokeWrite0()方法会触发outboud类型的handler的write方法
在传播的过程中会调用到编码器的write方法,和上一篇文章编码器类似的,抽象父类[MessageToByteEncoder]也是个模板方法,会让不同的编码器子类去实现不同的编码
2.invokeFlush0()方法会触发flush方法
三.编码器MessageToByteEncoder
抽象父类,看witre方法
就会进入到我们自定义的编码器代码中
public class MyEncode extends MessageToByteEncoder<Person> {
@Override
protected void encode(ChannelHandlerContext ctx, Person person, ByteBuf out) throws Exception {
long length = person.getLength();
out.writeShort((int) length);
out.writeBytes(person.getName().getBytes());
}
}
会把当前对象person里面的值写入到ByteBuf中,继续往下传播,最终会调用到头结点
io.netty.channel.DefaultChannelPipeline.HeadContext
@Override
public void read(ChannelHandlerContext ctx) {
unsafe.beginRead();
}
有前面的讲解可得知道,我们最终是unsafe类负责数据到写入和刷新, 继续进入
public final void write(Object msg, ChannelPromise promise) {
assertEventLoop();
ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
if (outboundBuffer == null) {
// If the outboundBuffer is null we know the channel was closed and so
// need to fail the future right away. If it is not null the handling of the rest
// will be done in flush0()
// See https://github.com/netty/netty/issues/2362
safeSetFailure(promise, WRITE_CLOSED_CHANNEL_EXCEPTION);
// release message now to prevent resource-leak
ReferenceCountUtil.release(msg);
return;
}
int size;
try {
msg = filterOutboundMessage(msg);
size = pipeline.estimatorHandle().size(msg);
if (size < 0) {
size = 0;
}
} catch (Throwable t) {
safeSetFailure(promise, t);
ReferenceCountUtil.release(msg);
return;
}
outboundBuffer.addMessage(msg, size, promise);
}
四.写bugger队列
哎,好累啊...干不动了