ByteToMessageDecoder是一个解码器,是一个ChannelInboundHandlerAdapter,它用来将ByteBuf中的字节流解析成另外的消息格式。它的核心方法是decode,
decode方法的in参数表示接收字节的来源,out参数表示节码之后输出的目的地。
比如,StringDecoder继承了ByteToMessageDecoder,它的decode方法代码如下:
ByteToMessageDecoder类不能被标记为@ChannelHandler.Sharable,因为ByteToMessageDecoder通常包含状态信息,共享的话会造成多线程问题。
自定义的类可以继承ByteToMessageDecoder,重写decode方法,示例:
package cn.edu.tju;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import java.nio.charset.Charset;
import java.util.List;
public class MyLongDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
int readIndex = in.readerIndex();
int writerIndex = in.writerIndex();
int readableBytes = in.readableBytes();
String str = (String) in.readCharSequence(writerIndex, Charset.defaultCharset());
long result = Long.parseLong(str);
out.add(result);
}
}
使用自定义的Decoder:
package cn.edu.tju;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import java.net.InetSocketAddress;
public class NettyTcpServer5 {
public static void main(String[] args) {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
EventLoopGroup businessGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup);
serverBootstrap.channel(NioServerSocketChannel.class);
MyLongDecoder myLongDecoder = new MyLongDecoder();
serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(businessGroup, myLongDecoder);
pipeline.addLast(businessGroup,new MyLongInboundHandler2());
}
});
ChannelFuture channelFuture = serverBootstrap.bind(new InetSocketAddress(8899))
.sync();
channelFuture.channel().closeFuture().sync();
} catch (Exception ex){
System.out.println(ex.getMessage());
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
package cn.edu.tju;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class MyLongInboundHandler2 extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
long result = (long)msg;
System.out.println(msg);
}
}