Netty多人与群组聊天
消息设计
图示:
public abstract class Packet {
/**
* 协议版本
*/
@JSONField(deserialize = false, serialize = false)
private Byte version = 1;
@JSONField(serialize = false)
public abstract Byte getCommand();
}
以上是通信过程中 Java 对象的抽象类,定义了一个版本号(默认值为 1 )以及一个获取指令的抽象方法,所有的指令数据包都必须实现这个方法,这样就可以知道某种指令的含义
如客户端请求登录消息:
LoginRequestPacket:
public class LoginRequestPacket extends Packet {
private String userName;
private String password;
@Override
public Byte getCommand() {
return LOGIN_REQUEST;
}
}
登录请求数据包继承自Packet,然后定义了三个字段,分别是用户 ID,用户名,密码,最为重要的就是覆盖了父类的 getCommand() 方法,值为常量 LOGIN_REQUEST。
其余消息图示:
编码以及解码
图示:
PacketCodec:
public class PacketCodec {
public static final int MAGIC_NUMBER = 0x12345678;
public static final PacketCodec INSTANCE = new PacketCodec();
private final Map<Byte, Class<? extends Packet>> packetTypeMap;
private final Map<Byte, Serializer> serializerMap;
private PacketCodec() {
packetTypeMap = new HashMap<>();
packetTypeMap.put(LOGIN_REQUEST, LoginRequestPacket.class);
packetTypeMap.put(LOGIN_RESPONSE, LoginResponsePacket.class);
packetTypeMap.put(MESSAGE_REQUEST, MessageRequestPacket.class);
packetTypeMap.put(MESSAGE_RESPONSE, MessageResponsePacket.class);
packetTypeMap.put(LOGOUT_REQUEST, LogoutRequestPacket.class);
packetTypeMap.put(LOGOUT_RESPONSE, LogoutResponsePacket.class);
packetTypeMap.put(CREATE_GROUP_REQUEST, CreateGroupRequestPacket.class);
packetTypeMap.put(CREATE_GROUP_RESPONSE, CreateGroupResponsePacket.class);
packetTypeMap.put(JOIN_GROUP_REQUEST, JoinGroupRequestPacket.class);
packetTypeMap.put(JOIN_GROUP_RESPONSE, JoinGroupResponsePacket.class);