简体   繁体   English

使用Netty 5编码和解码多种不同类型

[英]Encoding and Decoding multiple different types with Netty 5

I am trying to implement a network protocol with multiple different packet types. 我正在尝试使用多种不同的数据包类型实现网络协议。 The problem I am facing is the most "proper" way of implementing this with Netty. 我面临的问题是用Netty实现此问题的最“正确”方式。 I'll post some classes first, and then describe what I want to accomplish. 我将首先发布一些课程,然后描述我想要完成的工作。

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;
}

Now, all POJO that are transmitted across the network will have a packet identifier. 现在,所有通过网络传输的POJO都将具有一个数据包标识符。 This will be a 1-byte code that will let the decoder know what type of packet it is, and how to decode it. 这将是一个1字节的代码,它将使解码器知道它是什么类型的数据包,以及如何对其进行解码。

What would be the most appropriate way of handling this case? 处理此案的最合适方法是什么? Would it be better (read more conventional) to have one PacketDecoder class that extends the ByteToMessageDecoder which reads one byte, determines the type, and then in that same class, decode the packet with the appropriate method like so: 最好有一个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;
    }
}

Or would it be better to just add every type of decoder to the pipeline? 还是将每种类型的解码器添加到管道中会更好吗?

I did this in my own program and I used a single decoder because it was more straight forward thing to do. 我在自己的程序中做到了这一点,并使用了单个解码器,因为这样做更直接。 The only reason I could see for wanting multiple decoders would be if need to extend or dynamically changing the protocol your server understands. 我需要多个解码器的唯一原因是是否需要扩展或动态更改服务器可以理解的协议。 For example, maybe certain aspects of your server are free and others are paid for extensions that license key turns on then I could see this architecture being important. 例如,也许您服务器的某些方面是免费的,而另一些方面是为许可证密钥打开的扩展付费的,那么我可以看到这种体系结构很重要。 Or you load extensions to the protocol dynamically maybe. 或者您可以动态加载协议的扩展。 I think you need a real reason to segment decoding into several decoders besides it being architecturally pure. 我认为除了架构上纯洁之外,您还需要一个真正的理由将解码分为几个解码器。

In this case you can add multiple decoders to the pipeline, but each decoder needs to play nice and forward packets not meant for it along to the next decoder in the pipeline. 在这种情况下,您可以在管道中添加多个解码器,但是每个解码器都需要播放漂亮的数据包,并将不需要的数据包转发到管道中的下一个解码器。 You also have to be careful not to pull bytes off that down stream decoders might need. 您还必须小心,不要拉下下游解码器可能需要的字节。

Here is what I wouldn't do. 这是我不会做的。 A decoder per message architecture. 每个消息体系结构的解码器。 That will be cumbersome to write and maintain. 编写和维护起来很麻烦。 Since there is overhead with each decoder written to play nice and forward packets I wouldn't go through that exercise each time I write a decoder. 由于编写每个解码器来播放漂亮的转发数据包会产生开销,因此我每次编写解码器时都不会经过该练习。 You could overcome that with a nice base class to extend, but why go through all that hassle when you can just parse the first byte and do a simple if ladder? 您可以通过扩展一个不错的基类来克服它,但是当您仅解析第一个字节并执行一个简单的if梯形时,为什么要经历所有麻烦呢?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM