这是《手写RPC框架,我学会了什么?》系列的第06篇
埋坑篇 提到要用netty重写socket通信的部分。netty使用ByteBuf来作为数据交互的载体。在 上一篇 的基础上,需要分别实现一个编码器和解码器。
先通过测试用例,看一下要实现的效果:
/**
* @author nathan
* @date 2019/3/18
*/
public class CodecTest {
@Test
public void test() {
String expect = "hello, world.";
ByteBuf byteBuf = Unpooled.buffer(1024); // #1
RpcEncoder encoder = new RpcEncoder(String.class); // #2
encoder.encode(null, expect, byteBuf);
List<Object> decoded = new ArrayList<>();
RpcDecoder decoder = new RpcDecoder(String.class); // #3
decoder.decode(null, byteBuf, decoded);
Assert.assertEquals(expect, decoded.get(0));
}
}
#1 创建一个初始化容量为1024的byteBuf
#2 调用编码器把字符串转为byte数组,保存在byteBuf中
#3 调用解码器把byteBuf转为字符串,保存在decoded中
编码器
/**
* @author nathan
* @date 2019/3/18
*/
public class RpcEncoder extends MessageToByteEncoder {
private Class<?> typeClass;
public RpcEncoder(Class<?> typeClass) {
this.typeClass = typeClass;
}
@Override
public void encode(ChannelHandlerContext ctx, Object o, ByteBuf byteBuf) {
if (typeClass.isInstance(o)) {
byte[] data = SerializingUtil.serialize(o);
byteBuf.writeBytes(data);
}
}
}
解码器
/**
* @author nathan
* @date 2019/3/18
*/
public class RpcDecoder extends ByteToMessageDecoder {
private Class<?> typeClass;
public RpcDecoder(Class<?> typeClass) {
this.typeClass = typeClass;
}
@Override
public void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> decoded) {
int length = byteBuf.readableBytes();
byte[] bytes = new byte[length];
byteBuf.readBytes(bytes);
Object obj = SerializingUtil.deserialize(bytes, typeClass);
decoded.add(obj);
}
}
网友评论