Netty进阶之路-MessagePack编解码
Netty进阶之路-MessagePack编解码
- 前言
- MessagePack优点
- Netty客户端—MessagePack编解码
- Netty客户端—MessagePack编码
- Netty客户端—MessagePack解码
- Netty客户端—编解码使用
- Netty服务端—MessagePack编解码
- Netty服务端—MessagePack解码
- Netty服务端—MessagePack编码
- Netty服务端—编解码使用
前言
之前的Netty利用json和LineBasedFrameDecoder和StringDecoder来实现数据传输和解决粘包/半包问题。后来发现Netty支持更高效的编解码例如MessagePack。本篇主要来讲讲MessagePack的使用。
MessagePack优点
MessagePack是一个高效的二进制序列化框架
- 和json一样支持跨语言
- 序列化之后的码流更小
- 编解码性能高效
Netty客户端–MessagePack编解码
Netty提供了丰富的编解码器抽象基类,我们可以很容易的实现这些基类来自定义编解码器。
Netty客户端–MessagePack编码
这里将需要编码的对象加上@Message注解
我之前 result属性用的是Object 因为返回类型可能是List或者Map或者String等但是在MessagePack中不能使用Object 类型 所有我改成了String。
@Message
public class RPCRequest {
private String requestID;
private String className;
private String methodName;
private String[] parameters;
private String result;
public String getRequestID() {
return requestID;
}
public void setRequestID(String requestID) {
this.requestID = requestID;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public String[] getParameters() {
return parameters;
}
public void setParameters(String[] parameters) {
this.parameters = parameters;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
利用Netty基类来自定义编码器
public class ClientMsgPackEncode extends MessageToByteEncoder<Object>{
@Override
protected void encode(ChannelHandlerContext arg0, Object msg, ByteBuf out)
throws Exception {
RPCRequest request = (RPCRequest) msg;
MessagePack msgPack = new MessagePack();
//msgPack.register(RPCRequest.class);
byte[] raw = null;
raw = msgPack.write(request);
out.writeBytes(raw);
}
}
Netty客户端–MessagePack解码
@Message
public class RPCResponse {
private String requestID;
private String result;
public String getRequestID() {
return requestID;
}
public void setRequestID(String requestID) {
this.requestID = requestID;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
利用Netty基类来自定义解码器
public class ClientMsgPackDecode extends MessageToMessageDecoder<ByteBuf>{
@Override
protected void decode(ChannelHandlerContext arg0, ByteBuf msg,
List<Object> out) throws Exception {
// TODO Auto-generated method stub
final byte[] array;
final int length = msg.readableBytes();
array = new byte[length];
msg.getBytes(msg.readerIndex(), array, 0, length);
MessagePack msgPack = new MessagePack();
out.add(msgPack.read(array,RPCResponse.class));
}
}
Netty客户端–编解码使用
在链路里添加
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(65535, 0, 2,0,2));
ch.pipeline().addLast(new LengthFieldPrepender(2));
ch.pipeline().addLast(new ClientMsgPackEncode());//编码
ch.pipeline().addLast(new ClientMsgPackDecode());//解码
ch.pipeline().addLast(new RPCRequestHandler());//添加相应回调处理和编解码器
之后的发送消息和读取消息可以直接使用对象
Netty服务端–MessagePack编解码
说明一下 客户端服务端用了2套的原因是编解码的时候对象不是同一个
例如客户端编码是RPCRequest对象 服务端编码RPCResponse 对象。
Netty服务端–MessagePack解码
public class ServerMsgPackDecode extends MessageToMessageDecoder<ByteBuf>{
@Override
protected void decode(ChannelHandlerContext arg0, ByteBuf msg,
List<Object> out) throws Exception {
// TODO Auto-generated method stub
final byte[] array;
final int length = msg.readableBytes();
array = new byte[length];
msg.getBytes(msg.readerIndex(), array, 0, length);
MessagePack msgPack = new MessagePack();
out.add(msgPack.read(array,RPCRequest.class));
}
}
Netty服务端–MessagePack编码
public class ServerMsgPackEncode extends MessageToByteEncoder<Object>{
@Override
protected void encode(ChannelHandlerContext arg0, Object msg, ByteBuf out)
throws Exception {
RPCResponse RPCResponse = (RPCResponse) msg;
MessagePack msgPack = new MessagePack();
//msgPack.register(RPCResponse.class);
byte[] raw = null;
raw = msgPack.write(RPCResponse);
out.writeBytes(raw);
}
}
Netty服务端–编解码使用
同样在链路里添加
socketChannel.pipeline().addLast(new LengthFieldBasedFrameDecoder(65535, 0, 2,0,2));//编码
socketChannel.pipeline().addLast(new LengthFieldPrepender(2));
socketChannel.pipeline().addLast(new ServerMsgPackEncode());//编码
socketChannel.pipeline().addLast(new ServerMsgPackDecode());//解码
socketChannel.pipeline().addLast(new RPCResponseHandler());//处理类
还没有评论,来说两句吧...