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. 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. This will be a 1-byte code that will let the decoder know what type of packet it is, and how to decode it.
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:
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?