我不清楚,是否需要在基于MessageToMessageDecoder构建自定义POJO解码器时使用像LineBasedFrameDecoder这样的帧解码器?
在StringDecoder的Netty源代码中指出frame decoder must be used together with the StringDecoder。
我想是的,为什么买?
答案 0 :(得分:0)
我问自己这是否应该作为答案;您可以使用所需的任何实现。 JavaDocs提供了有关如何编码/解码字符串数据的示例。您可以实现自己的处理程序并确定字符串的开始和停止。
例如,我实现了自己的数据包协议,该协议混合了在线视频游戏的大量数据。所以我通过先读取varint然后再读取字符串来解码我的字符串。我可以采用相同的逻辑,并创建自己的处理程序以解码StringDecoder处理程序之前的字符串长度。
编码器
public static ByteBuf encodeString(ByteBuf out, String value, Charset charset) {
byte[] bytes = value.getBytes(charset);
encodeArray(out, bytes);
return out;
}
public static ByteBuf encodeArray(ByteBuf out, byte[] bytes) {
int length = bytes.length;
encodeInteger(out, length);
out.writeBytes(bytes);
return out;
}
public static ByteBuf encodeInteger(ByteBuf out, int number) {
return encodeInt(out, number, computeUInt32Size(number));
}
public static ByteBuf encodeInt(ByteBuf out, int number, int numBytes) {
int originalIndex = out.writerIndex();
int adjustedI = originalIndex + numBytes;
final int capacity = out.capacity();
if (adjustedI > capacity) {
out.capacity(adjustedI);
}
out.writerIndex(out.writerIndex() + numBytes);
for (int i = adjustedI - 1; i >= originalIndex; i--) {
int curByte = (number & 0x7F);
if (i != (adjustedI - 1)) {
curByte |= 0x80;
}
out.setByte(i, curByte);
number >>>= 7;
}
return out;
}
public static int computeUInt32Size(int value) {
if ((value & (~0 << 7)) == 0) {
return 1;
}
if ((value & (~0 << 14)) == 0) {
return 2;
}
if ((value & (~0 << 21)) == 0) {
return 3;
}
if ((value & (~0 << 28)) == 0) {
return 4;
}
return 5;
}
解码器
public static String unsafeDecodeString(ByteBuf in, Charset standardCharsets) {
byte[] bytes = unsafeDecodeArray(in);
return new String(bytes, standardCharsets);
}
public static byte[] unsafeDecodeArray(ByteBuf in) {
int len = unsafeDecodeInteger(in);
return unsafeDecodeArray(in, len);
}
public static byte[] unsafeDecodeArray(ByteBuf in, int len) {
byte[] bytes = new byte[len];
in.readBytes(bytes, 0, len);
return bytes;
}
// This is unsafe as we do not check readable bytes, is safe if apart of a packet read all at // once
public static int unsafeDecodeInteger(ByteBuf in) {
int n = 0;
for (int i = 0; i <= 8; i++) {
int curByte = in.readByte();
n = (n << 7) | (curByte & 0x7f);
if ((curByte & 0x80) == 0) {
break;
}
}
return n;
}
答案 1 :(得分:0)
Netty源代码中的注释引发了一个奇怪的问题。
要回答我自己的问题:这取决于! 如果没有固定长度的数据帧,则需要某种方式让客户端和服务器双方就何时结束数据帧达成共识–完成。它可能很简单,例如\ r \ n(回车+换行符)或其他已同意的字符。