首发于Enaium的个人博客
先写一个Messsage
类,解码的时候将要把ByteBuf
解码为Message
public class Message implements Serializable {
private final String data;
public Message(String data) {
this.data = data;
}
@Override
public String toString() {
return "Message{" +
"data='" + data + '\'' +
'}';
}
}
之后创建MessageCodec
类,继承MessageToMessageCodec
入站为ByteBuf
解码为Message
,出站为Message
编码为ByteBuf
重写编码的解码方法
public class MessageCodec extends MessageToMessageCodec<ByteBuf, Message> {
@Override
public void encode(ChannelHandlerContext channelHandlerContext, Message message, List<Object> list) throws Exception {
}
@Override
public void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
}
}
这里用四个字节表示内容的长度,最后是所有内容,这里使用JDK来序列化
public void encode(ChannelHandlerContext channelHandlerContext, Message message, List<Object> list) throws Exception {
ByteBuf buffer = channelHandlerContext.alloc().buffer();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(message);
byte[] bytes = byteArrayOutputStream.toByteArray();
buffer.writeInt(bytes.length);
buffer.writeBytes(bytes);
list.add(buffer);
}
怎么编码的就怎么解码,读取长度读取内容
public void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
int length = byteBuf.readInt();
byte[] bytes = new byte[length];
byteBuf.readBytes(bytes);
ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
Message message = (Message) objectInputStream.readObject();
System.out.println("message = " + message);
list.add(message);
}
一个简单的协议就写好了,现在就来测试一下
使用EmbeddedChannel
这个Channel
来进行测试,处理器就添加一个日志处理器和刚才写好的编解码器
写入Message
EmbeddedChannel embeddedChannel = new EmbeddedChannel(new LoggingHandler(LogLevel.INFO), new MessageCodec());
embeddedChannel.writeOutbound(new Message("HELLO WORLD"));
运行一下试试
写入了92
个字节的数据,长度为0x58
转为10进制为88
加上长度占的4
个字节刚好92
个字节
信息: [id: 0xembedded, L:embedded - R:embedded] WRITE: 92B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 00 58 ac ed 00 05 73 72 00 19 63 6e 2e 65 |...X....sr..cn.e|
|00000010| 6e 61 69 75 6d 2e 6d 65 73 73 61 67 65 2e 4d 65 |naium.message.Me|
|00000020| 73 73 61 67 65 95 ee d0 49 e2 3a be 6d 02 00 01 |ssage...I.:.m...|
|00000030| 4c 00 04 64 61 74 61 74 00 12 4c 6a 61 76 61 2f |L..datat..Ljava/|
|00000040| 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 78 70 74 00 |lang/String;xpt.|
|00000050| 0b 48 45 4c 4c 4f 20 57 4f 52 4c 44 |.HELLO WORLD |
+--------+-------------------------------------------------+----------------+
接着测试解码,这里粗暴的使用了刚才的日志
embeddedChannel.writeInbound(Unpooled.wrappedBuffer(new byte[]{
0x00, 0x00, 0x00, 0x58, (byte) 0xac, (byte) 0xed, 0x00, 0x05, 0x73, 0x72, 0x00, 0x19, 0x63, 0x6e, 0x2e, 0x65,
0x6e, 0x61, 0x69, 0x75, 0x6d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, (byte) 0x95, (byte) 0xee, (byte) 0xd0, 0x49, (byte) 0xe2, 0x3a, (byte) 0xbe, 0x6d, 0x02, 0x00, 0x01,
0x4c, 0x00, 0x04, 0x64, 0x61, 0x74, 0x61, 0x74, 0x00, 0x12, 0x4c, 0x6a, 0x61, 0x76, 0x61, 0x2f,
0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3b, 0x78, 0x70, 0x74, 0x00,
0x0b, 0x48, 0x45, 0x4c, 0x4c, 0x4f, 0x20, 0x57, 0x4f, 0x52, 0x4c, 0x44
}));
读取了92个字节,也成功解码
信息: [id: 0xembedded, L:embedded - R:embedded] READ: 92B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 00 58 ac ed 00 05 73 72 00 19 63 6e 2e 65 |...X....sr..cn.e|
|00000010| 6e 61 69 75 6d 2e 6d 65 73 73 61 67 65 2e 4d 65 |naium.message.Me|
|00000020| 73 73 61 67 65 95 ee d0 49 e2 3a be 6d 02 00 01 |ssage...I.:.m...|
|00000030| 4c 00 04 64 61 74 61 74 00 12 4c 6a 61 76 61 2f |L..datat..Ljava/|
|00000040| 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 78 70 74 00 |lang/String;xpt.|
|00000050| 0b 48 45 4c 4c 4f 20 57 4f 52 4c 44 |.HELLO WORLD |
+--------+-------------------------------------------------+----------------+
message = Message{data='HELLO WORLD'}
一个简单的协议就写好了