在测试的处理器—AbsIntegerEncoder,它是 Netty 的 MessageToMessageEncoder 的一个特殊化的实现,用于将负值整数转换为绝对值。
该示例将会按照下列方式工作:
持有 AbsIntegerEncoder 的 EmbeddedChannel 将会以 4 字节的负整数的形式写出站数据;
编码器将从传入的 ByteBuf 中读取每个负整数,并将会调用 Math.abs()方法来获取其绝对值;
编码器将会把每个负整数的绝对值写到 ChannelPipeline 中。
AbsIntegerEncoderTest
package cn.enjoyedu.nettybasic.embedded;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.embedded.EmbeddedChannel;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* 作者:Mark/Maoke
* 创建日期:2018/08/26
* 类说明:测试出站处理,可以通过修改AbsIntegerEncoder看运行结果
*/
public class AbsIntegerEncoderTest {
@Test
public void testEncoded() {
//(1) 创建一个 ByteBuf,并且写入 9 个负整数
ByteBuf buf = Unpooled.buffer();
for (int i = 1; i < 10; i++) {
buf.writeInt(i * -1);
}
//(2) 创建一个EmbeddedChannel,并安装一个要测试的 AbsIntegerEncoder
EmbeddedChannel channel = new EmbeddedChannel(
new AbsIntegerEncoder());
//(3) 写入 ByteBuf,并断言调用 readOutbound()方法将会产生数据
assertTrue(channel.writeOutbound(buf));
//(4) 将该 Channel 标记为已完成状态
assertTrue(channel.finish());
// read bytes
//(5) 读取所产生的消息,并断言它们包含了对应的绝对值
for (int i = 1; i < 10; i++) {
int x = channel.readOutbound();
assertEquals(i, x);
}
assertNull(channel.readOutbound());
}
}
AbsIntegerEncoder
package cn.enjoyedu.nettybasic.embedded;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
/**
* AbsIntegerEncoder
*/
//扩展 MessageToMessageEncoder 以将一个消息编码为另外一种格式
public class AbsIntegerEncoder extends
MessageToMessageEncoder<ByteBuf> {
@Override
protected void encode(ChannelHandlerContext channelHandlerContext,
ByteBuf in, List<Object> out) throws Exception {
//检查是否有足够的字节用来编码,int为4个字节
while (in.readableBytes() >= 4) {
//从输入的 ByteBuf中读取下一个整数,并且计算其绝对值
int value = Math.abs(in.readInt());
//将该整数写入到编码消息的 List 中
out.add(value);
}
}
}