我正在尝试实现一个具有多种不同数据包类型的网络协议。我所面临的问题是用Netty实现这一点的最“正确”的方法。我将首先发布一些类,然后描述我想要完成的任务。
public class ItemStack {
public ItemStack(final int item, final int amount) {
if (item < 0) {
throw new IllegalArgumentException("item must be non-negative integer: " + item);
}
if (amount < 1) {
throw new IllegalArgumentException("amount must be positive integer: " + amount);
}
this.item = item;
this.amount = amount;
}
public int getItem() {
return item;
}
public int getAmount() {
return amount;
}
private final int item;
private final int amount;
}
public class ChatMessage {
public ChatMessage(final String playerName, final String message) {
if (playerName == null) {
throw new IllegalArgumentException("playerName must not be null");
}
if (message == null) {
throw new IllegalArgumentException("message must not be null");
}
this.playerName = playerName;
this.message = message;
}
public String getPlayerName() {
return playerName;
}
public String getMessage() {
return message;
}
private final int playerName;
private final int message;
}
现在,通过网络传输的所有POJO都有一个数据包标识符。这将是一个1字节的代码,让解码器知道它是什么类型的数据包,以及如何解码它。
处理这个案件最合适的方法是什么?如果有一个PacketDecoder类扩展ByteToMessageDecoder,该类读取一个字节,确定类型,然后在同一类中用如下的适当方法解码数据包,会更好(阅读更传统)吗?
public class PacketDecoder extends ByteToMessageDecoder {
protected void decode(
final ChannelHandlerContext context, final ByteBuf buf, List<Object> objects) throws Exception {
if (buf.readableBytes < 1) {
return;
}
final int opcode = buf.readByte() & 0xff;
final Packet packet = decodePacket(opcode);
objects.add(packet);
}
private Packet decodePacket(final int opcode, final ByteBuf buf) {
if (buf == null) {
throw new IllegalArgumentException("buf must not be null");
}
Packet packet = null;
switch (opcode) {
case 0:
packet = decodeItemStack(buf);
break;
case 1:
packet = decodeChatMessage(buf);
break;
// ...
}
return packet;
}
}
还是将每种类型的解码器添加到流水线中更好呢?
发布于 2014-04-29 23:54:56
我在我自己的程序中这样做,我使用了一个解码器,因为它更直接的事情要做。我看到需要多个解码器的唯一原因是如果需要扩展或动态更改服务器所理解的协议。例如,您的服务器的某些方面可能是免费的,而其他的则是为许可密钥打开的扩展付费的,然后我可以看到这个体系结构是很重要的。或者您可以动态地加载协议的扩展。我认为你需要一个真正的理由来将解码分割成几个解码器,而且它在架构上是纯的。
在这种情况下,您可以添加多个解码器到管道,但每个解码器需要播放良好的和转发的数据包,而不是意味着要在管道中的下一个解码器。您还必须小心,不要从下游解码器可能需要的字节中提取字节。
以下是我不会做的事。每个消息结构的解码器。这将是繁琐的编写和维护。由于每一个译码器的开销都是为了播放漂亮的和转发的数据包,所以每次编写解码器时,我都不会进行这种操作。你可以用一个很好的基类来扩展它,但是当你只需要解析第一个字节并做一个简单的if梯子的时候,为什么要经历这些麻烦呢?
https://stackoverflow.com/questions/23377089
复制相似问题