這是《手寫RPC框架宁仔,我學(xué)會了什么稠屠?》系列的第06篇
埋坑篇 提到要用netty重寫socket通信的部分。netty使用ByteBuf來作為數(shù)據(jù)交互的載體翎苫。在 上一篇 的基礎(chǔ)上权埠,需要分別實現(xiàn)一個編碼器和解碼器。
先通過測試用例煎谍,看一下要實現(xiàn)的效果:
/**
* @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 創(chuàng)建一個初始化容量為1024的byteBuf
#2 調(diào)用編碼器把字符串轉(zhuǎn)為byte數(shù)組攘蔽,保存在byteBuf中
#3 調(diào)用解碼器把byteBuf轉(zhuǎn)為字符串,保存在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);
}
}