Netty的Decoder Handler 处理流程

数据从客户端传递为ByteBuf类型,可以先经过实现自定义 ByteToMessageDecoder 实现类对ByteBuf数据进行初步转换(比如字符串),如下代码实现将ByteBuf数据转为String数据,

public class MyDecoder extends ByteToMessageDecoder {  //自定义解码器

    @Override
    public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
            throws Exception {
        if (in.readableBytes() >= 4) {  //判断读取数据是否可读
            // 待处理的消息包
            byte[] bytesReady = new byte[in.readableBytes()];
            in.readBytes(bytesReady);
            // 将字节数据转为字符串并去除首尾换行和空格
            // 此处的转换后的字符串类型是下一个Handler接收的消息类型
            out.add(new String(bytesReady).trim());
        }
    }
}

decoder执行完成之后channelPipeline会自动调用 fireChannelRead(Object msg) 方法,此方法调用后续处理String类型消息的Handler,此时可以对字符串消息进行一定的处理,比如验证字符串时候符合一定的格式,或者能否转换为指定的对象类型,如下代码实现将符合JSON格式的String消息转为指定的消息对象:

/**
 * @author madechao
 * @menu
 * @description
 * @createTime 17:08 2021/1/28
 */
public class StringMessageServerHandler extends SimpleChannelInboundHandler<String> {
    @Data
    class Message{    // 示例消息类型
        private String message;
        private String toWho;
        private String fromWho;
        private Date sendTime;
    }
    @Override
    public void channelRead0(ChannelHandlerContext ctx, String message) throws Exception {
        System.out.println("handler received message:" + message);
        if (StringUtil.isNullOrEmpty(message)){    // 消息为空不进行处理
            return;
        }
        // 拿到传过来的msg数据,开始处理,将字符串转为Message对象
        Message msg = JSONObject.parseObject(message, Message.class);
        // 自定义Handler处理完之后不会ChannelPipeline不会主动调用下一Handler
        // 此处需主动调用fireChannelRead()方法并将处理后的Message对象转交给下一个Handler
        ctx.fireChannelRead(msg);
    }
}

最近练习netty对decoder和handler的处理流程的总结,如有不正确的地方欢迎大家批评指正

上一篇:文献及代码阅读报告 - SS-LSTM:A Hierarchical LSTM Model for Pedestrian Trajectory Prediction


下一篇:MediaCodec支持的类型