MessagePack编解码
MessagePack Java 模块 GitHub 开源地址:https://github.com/msgpack/msgpack-java
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack</artifactId>
<version>0.6.12</version>
</dependency>
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack-core</artifactId>
<version>0.9.0</version>
</dependency>
import org.msgpack.MessagePack;
import org.msgpack.core.MessageBufferPacker;
import org.msgpack.core.MessageUnpacker;
import org.msgpack.template.Templates;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class MessagePackDemo1 {
public static void main(String...args) throws IOException {
List<String> src = new ArrayList<>();
src.add("msgpack");
src.add("kumofs");
src.add("viver");
// msgpack 使用
MessagePack messagePack = new MessagePack();
// serialize
byte[] raw = messagePack.write(src);
// deserialize
List<String> dst = messagePack.read(raw, Templates.tList(Templates.TString));
System.out.println(dst.get(0));
System.out.println(dst.get(1));
System.out.println(dst.get(2));
// msgpack-core 使用
//数据打包
MessageBufferPacker packer = org.msgpack.core.MessagePack.newDefaultBufferPacker();
packer.packArrayHeader(src.size());
for (String s : src) {
packer.packString(s);
}
packer.close();
byte[] raw1 = packer.toMessageBuffer().toByteArray();
// 数据解包
MessageUnpacker unpacker = org.msgpack.core.MessagePack.newDefaultUnpacker(raw1);
int i = unpacker.unpackArrayHeader();
List<String> dst1 = new ArrayList<>();
for (int j = 0; j < i; j++) {
dst1.add(unpacker.unpackString());
}
System.out.println(dst1.get(0));
System.out.println(dst1.get(1));
System.out.println(dst1.get(2));
}
}
MessagePack 编/解码器 使用
UserInfo
import org.msgpack.annotation.Message;
import java.io.Serializable;
import java.nio.ByteBuffer;
@Message
public class UserInfo implements Serializable {
private String userName;
private int userId;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}import org.msgpack.annotation.Message;
import java.io.Serializable;
import java.nio.ByteBuffer;
@Message
public class UserInfo implements Serializable {
private String userName;
private int userId;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
}
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import org.msgpack.MessagePack;
import java.util.List;
/**
* Msgpack 解码器
*/
public class MsgpackDecoder extends MessageToMessageDecoder<ByteBuf> {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
final byte[] array;
final int length = msg.readableBytes();
array = new byte[length];
msg.getBytes(msg.readerIndex(), array, 0, length);
MessagePack messagePack = new MessagePack();
out.add(messagePack.read(array));
}
}
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import org.msgpack.MessagePack;
/**
* Msgpack 编码器
* 将Object类型的对象编码为byte数组,然后写入ByteBuf中
*/
public class MsgpackEncoder extends MessageToByteEncoder<Object> {
@Override
protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
MessagePack messagePack = new MessagePack();
byte[] raw = messagePack.write(msg);
out.writeBytes(raw);
}
}
import com.fly.demo.decoder.MsgpackDecoder;
import com.fly.demo.encoder.MsgpackEncoder;
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.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import java.net.InetSocketAddress;
/**
* Msgpack 编/解码器 使用
*/
public class MsgPackEchoServer {
public static void main(String...args) throws InterruptedException {
EventLoopGroup parent = new NioEventLoopGroup();
EventLoopGroup child = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(parent, child)
.localAddress(new InetSocketAddress(8080))
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// LengthFieldBasedFrameDecoder处理半包消息
// 公式: 发送数据包长度 = 长度域的值 + lengthFieldOffset + lengthFieldLength + lengthAdjustment
ch.pipeline().addLast("frameDecoder" , new LengthFieldBasedFrameDecoder(
65535, //发送的数据帧最大长度
0, //长度域的开始地方
2,//定义的长度域的长度
0, // = 数据包长度 - lengthFieldOffset - lengthFieldLength - 长度域的值
2 //解码过程中,没有丢弃前2位
));
ch.pipeline().addLast("msgpack decoder", new MsgpackDecoder());
// LengthFieldPrepender将在ByteBuf之前增加2个字节的消息长度字段
ch.pipeline().addLast("frameEncoder", new LengthFieldPrepender(2));
ch.pipeline().addLast("msgpack encoder", new MsgpackEncoder());
ch.pipeline().addLast(new EchoServerHandler());
}
});
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
}finally {
parent.shutdownGracefully().sync();
child.shutdownGracefully().sync();
}
}
@ChannelHandler.Sharable
private static class EchoServerHandler extends ChannelInboundHandlerAdapter{
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("Server receive the msgpack message : " + msg);
ctx.writeAndFlush(msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
}
import com.fly.demo.decoder.MsgpackDecoder;
import com.fly.demo.encoder.MsgpackEncoder;
import com.fly.demo.serial.UserInfo;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import java.net.InetSocketAddress;
/**
* Msgpack 编/解码器 使用
*/
public class MsgPackEchoClient {
public static void main(String... args) throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.remoteAddress(new InetSocketAddress(8080))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("frameDecoder", new LengthFieldBasedFrameDecoder(65535, 0, 2, 0, 2));
ch.pipeline().addLast("msgpack decoder", new MsgpackDecoder());
ch.pipeline().addLast("frameEncoder", new LengthFieldPrepender(2));
ch.pipeline().addLast("msgpack encoder", new MsgpackEncoder());
ch.pipeline().addLast(new EchoClientHandler());
}
});
ChannelFuture f = b.connect().sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
}
}
private static class EchoClientHandler extends ChannelInboundHandlerAdapter {
final int sendNumber = 10;
private UserInfo[] getUserArray(int userNum) {
UserInfo[] userInfos = new UserInfo[userNum];
UserInfo userInfo = null;
for (int i = 0; i < userNum; i++) {
userInfo = new UserInfo();
userInfo.setUserId(i);
userInfo.setUserName("ABCDEFG-->" + i);
userInfos[i] = userInfo;
}
return userInfos;
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
UserInfo[] userInfos = getUserArray(sendNumber);
for (UserInfo infoE : userInfos) {
ctx.writeAndFlush(infoE);
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("Client receive the msgpack message : " + msg);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
}

浙公网安备 33010602011771号