Netty 自定义编码器

2021-08-30 09:58:28

Netty 设计最优良的部分就是编码器的架构,可以方便的自定义协议的处理,也可以复用优秀的通用协议。现简单定义一个编码器用来记录。
假设这样一个场景,服务端与客户端希望传输 Map 类型对象,这样足够灵活,尽管效率会很低,但是简单灵活,每一条消息都是个 Map ,每种业务都可以灵活的支持,尽管效率不够高效,但是节省脑细胞。
那么具体的过程是:定义Map消息 -> Map编码至String -> 发送 -> 将String解码为 Map -> 处理 Map 消息
这样看需要定义一个编码器和一个解码器

解码器

// MapDecoder.java 解码器

public class MapDecoder extends MessageToMessageDecoder<String> {
    @Override
    protected void decode(ChannelHandlerContext ctx, String msg, List<Object> out) throws Exception {
        System.out.println("decode: " + msg);

        //PusherCoder.decode可以是任何你喜欢的将json转换成map的工具。
        Map<String,Object> map = PusherCoder.decode(msg);

        if(map != null && map.size() > 0){
            out.add(map);

        }
    }
}

编码器

// MapDecoder.java 解码器

public class MapEncoder extends MessageToMessageEncoder<Map<String,Object>> {
    @Override
    protected void encode(ChannelHandlerContext ctx, Map<String,Object> msg, List<Object> out) throws Exception {
        System.out.println("encode :" + msg);
        
        //PusherCoder.encode可以是任何你喜欢的将map转换成json字符串的工具
        String str = PusherCoder.encode(msg);
        
        //因为使用换行符作分隔符
        out.add(str + System.getProperty("line.separator"));
    }
}

消息处理

//NettyServiceHandler.java 这是服务端的消息处理器,客户端也是类似的,在这里直接可以处理 map 格式的消息
public class NettyServiceHandler extends SimpleChannelInboundHandler<Map<String, Object>> {
    private Integer count = 0;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Map<String, Object> msg) throws Exception {
        System.out.println("NettyServiceHandler channelRead0");
        System.out.println(msg);
        ctx.channel().writeAndFlush(msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
        super.exceptionCaught(ctx, cause);

    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        System.out.println("NettyServiceHandler channelActive");

    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        System.out.println("NettyServiceHandler channelInactive");
    }

}

以上,是一个很偷懒的,不够实用的,不够高效的自定义编解码器,但是对于一面设计一面上线,用户量不高的场景来说还是可以用的。

Copyright tg-blog 京ICP备15066502号-2