之前我们已经介绍了Netty中各种解码器的解码过程,本节我们就来看一下它是如何编码的,下面是我们添加的两个handler:
ch.pipeline().addLast(new Encoder());
ch.pipeline().addLast(new BizHandler());
第一个handler我们来看一下里面做了什么:
public class Encoder extends MessageToByteEncoder<User> {
@Override
protected void encode(ChannelHandlerContext ctx, User user, ByteBuf out) throws Exception {
byte[] bytes = user.getName().getBytes();
out.writeInt(4 + bytes.length);
out.writeInt(user.getAge());
out.writeBytes(bytes);
}
}
其实就是覆盖了一个encode方法,再看一下另外一个handler:
public class BizHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//...
User user = new User(19, "zhangsan");
ctx.channel().writeAndFlush(user);
}
}
就是向我们的channel中写了一个对象,那么我们就从这个地方开始分析:
public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {
return pipeline.writeAndFlush(msg, promise);
}
然后套调用了pipeline的writeAndFlush方法,这个时候msg是我们传进去的user对象:
public final ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {
return tail.writeAndFlush(msg, promise);
}
我们发现当调用writeAndFlush方法的时候是从处理链的尾部开始执行的:
public ChannelFuture writeAndFlush(Object msg, ChannelPromise promise) {
if (msg == null) {
throw new NullPointerException("msg");
}
if (!validatePromise(promise, true)) {
ReferenceCountUtil.release(msg);
// cancelled
return promise;
}
write(msg, true, promise);
return promise;
}
在这个方法中首先对我们传进的参数进行调用,最终嗲用了write方法:
private void write(Object msg, boolean flush, ChannelPromise promise) {
//找到下一个出结点
AbstractChannelHandlerContext next = findContextOutbound();
final Object m = pipeline.touch(msg, next);
//获得下一个出结点绑定的处理器
EventExecutor executor = next.executor();
//判断处理器是否和当前线程绑定的一致
if (executor.inEventLoop()) {
//根据是否flush调用不同的方法
if (flush) {
next.invokeWriteAndFlush(m, promise);
} else {
next.invokeWrite(m, promis