netty的编解码器,以及内置的编解码器

一、编码器和解码器

1、什么是编码和解码

解码常用于入站操作,将字节转换为消息。编码用于出站,将消息转换为字节流

2、解码器ByteToMessageDecoder和ReplayingDecoder,ReplayingDecoder扩展了ByteToMessageDecoder类,使得我们不必使用readableBytes()方法,下面是两类测试代码

复制代码
public class ToIntegerDecoder extends ByteToMessageDecoder {
    @Override
    public void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> list) throws Exception {
        if(in.readableBytes() >=4) {
            list.add(in.readInt());
        }
    }
}

public class ToIntegerDecoder2 extends ReplayingDecoder<Void> {
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        list.add(byteBuf.readInt());
    }
}

3、编码器MessageToByteEncoder和MessageToMessageEncoder,其中T是原始消息的类型,这两个类分别代表将消息转换为字节流和将消息转换为其他类型的消息。下面代码分别为这两种的示例代码

复制代码
public class ShortToByteEncoder extends MessageToByteEncoder<Short> {
    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, Short aShort, ByteBuf byteBuf) throws Exception {
        byteBuf.writeShort(aShort);
    }
}

public class IntegerToStringEncoder extends MessageToMessageEncoder<Integer> {
    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, Integer integer, List<Object> list) throws Exception {
        list.add(String.valueOf(integer));
    }
}

4、抽象的编解码器

ByteToMessageCodec:对编码和解码的整合,可以理解为对消息解码后再次编码。

MessageToMessageCodec:原理和ByteToMessageCodec同理。

二、内置的编码器和解码器

1、通过SSL/TTL保护的netty程序,通常是将SslHandler放在ChannelPipeline的头部,示例代码如下:

复制代码
public class SslChannelInitializer extends ChannelInitializer<Channel> {

    private final SslContext sslContext;

    private final boolean startTls;

    public SslChannelInitializer(SslContext sslContext, boolean startTls) {
        this.sslContext = sslContext;
        this.startTls = startTls;//如果设置为true,第一个被写入的消息将不会被加密
    }

    @Override
    protected void initChannel(Channel channel) throws Exception {
        SSLEngine sslEngine = sslContext.newEngine(channel.alloc());
        channel.pipeline().addFirst("ssl", new SslHandler(sslEngine,startTls));
    }
}

2、构建netty基于http/https协议的:客户端和服务器分别用HttpClientCodec和HttpServerCodec类即可。

复制代码
public class HttpInitializer extends ChannelInitializer<Channel> {
    private final SslContext sslContext;
    private final boolean isClient;

    public HttpInitializer(SslContext sslContext, boolean isClient) {
        this.sslContext = sslContext;
        this.isClient = isClient;
    }

    @Override
    protected void initChannel(Channel channel) throws Exception {
        //如果是https协议,则需要在通道下的管道头部追加SslHandler
        ChannelPipeline pipeline = channel.pipeline();
        SSLEngine engine = sslContext.newEngine(channel.alloc());
        pipeline.addFirst("ssl", new SslHandler(engine));
        if(isClient){
            pipeline.addLast("codec", new HttpClientCodec());
        }else {
            pipeline.addLast("codec", new HttpServerCodec());
        }
    }
}

3、websocket:websocket的WebSocketFrame类型通常包括BinaryWebSocketFrame(数据帧,二进制数据)、TextWebSocketFrame(数据帧,文本数据)、CloseWebSocketFrame(控制帧,一个Close请求、关闭的状态码及关闭的原因)、PingWebSocketFrame(控制帧,请求一个PongWebSocketFrame)和PongWebSocketFrame(控制帧,对PingWebSocketFrame进行响应)。

示例代码

websocket的处理类

复制代码
public class TextFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    @Override
    public void messageReceived(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame) throws Exception {

    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception{
        //处理数据
    }
}

public class WebsocketServerInitializer extends ChannelInitializer<Channel> {
    @Override
    public void initChannel(Channel ch) throws Exception {
        ch.pipeline().addLast(new HttpServerCodec(),
                new HttpObjectAggregator(65536),
                new WebSocketServerProtocolHandler("/websocket"),
                new TextFrameHandler()
        );
    }
}

4、空闲的连接和超时

IdleStateHandler:当连接空闲时间太长会触发事件。ReadTimeoutHandler读超时处理器,WriteTimeoutHandler写超时处理器

用法也是将他们的对象注册到通道里的管道中去。

复制代码
channel.pipeline().addLast(new IdleStateHandler(0, 0, 60, TimeUnit.SECONDS));
相关推荐
JH30738 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
Coder_Boy_9 小时前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
invicinble9 小时前
对tomcat的提供的功能与底层拓扑结构与实现机制的理解
java·tomcat
较真的菜鸟9 小时前
使用ASM和agent监控属性变化
java
黎雁·泠崖10 小时前
【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理
java·开发语言
qq_124987075311 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
Coder_Boy_11 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
Mr_sun.11 小时前
Day06——权限认证-项目集成
java
瑶山11 小时前
Spring Cloud微服务搭建四、集成RocketMQ消息队列
java·spring cloud·微服务·rocketmq·dashboard
abluckyboy11 小时前
Java 实现求 n 的 n^n 次方的最后一位数字
java·python·算法