iohao / ioGame

无锁异步化、事件驱动架构设计的 java netty 网络编程框架; 轻量级,无需依赖任何第三方中间件或数据库就能支持集群、分布式; 适用于网络游戏服务器、物联网、内部系统及各种需要长连接的场景; 通过 ioGame 你可以很容易的搭建出一个集群无中心节点、集群自动化、分布式的网络服务器;FXGL、Unity、UE、Cocos Creator、Godot、Netty、Protobuf、webSocket、tcp、socket;java Netty 游戏服务器框架; Java Netty Game Server.
http://game.iohao.com
GNU Affero General Public License v3.0
918 stars 205 forks source link

List<枚举>要求 must has default constructor method with no parameters #348

Closed SaltedFishKnight closed 3 months ago

SaltedFishKnight commented 3 months ago

我有一个协议类 Movement,包含以下字段: public ByteValueList commandList; public int id;

假设客户端要发送 Movement LinkedList commands = new LinkedList<>();(CommandType 是枚举类) (省略添加 CommandType 对象的代码) 执行以下语句出错 commandList = WrapperKit.ofListByteValue(commands); java.lang.IllegalArgumentException: Class 'org.king.iogate.common.protobuf.room.CommandType' must has default constructor method with no parameters.

枚举类的构造器是 private 的,我是否只能在业务协议上做出更改,避免 List<枚举> 出现

iohao commented 3 months ago

直接序列化单个枚举值或枚举值 list 没有试过,可以到 https://github.com/jhunters/jprotobuf/issues 交流下。

但协议类内的枚举属性是可以的,如下

@ProtobufClass
public class Movement {
    List<AnimalType> animalTypeList;
}

@ProtobufClass
public enum AnimalType {
    BIRD,
    CAT;
}
SaltedFishKnight commented 3 months ago
@ProtobufClass
public class Movement {
    List<AnimalType> animalTypeList;
}

@ProtobufClass
public enum AnimalType {
    BIRD,
    CAT;
}

假如 Java 客户端要传输 Movement 的话,animalTypeList 的编译类型为什么不是 ByteValueList 直接使用 JDK 的 List 实现类是不能直接序列化的,难道我要自定义 List 实现来支持 @ProtobufClass?

因为 JDK 的 List 实现类都没有支持 @ProtobufClass,需要用 WrapperKit.ofListByteValue(),将 List 编码为 List<byte[]>,并用 ByteValueList 包装 这时又回到一开始的问题了,WrapperKit.ofListByteValue 要求,作为泛型的类的构造器,是默认的无参构造器,而枚举类的构造器是 private 的

解决协议碎片 “如果游戏客户端想发送 List 数据,也需要使用 ByteValueList 来包装”

iohao commented 3 months ago

假如 Java 客户端要传输 Movement 的话,animalTypeList 的编译类型为什么不是 ByteValueList

因为 animalTypeList 不是 ByteValueList,两者类型不同。

ByteValueList 包装的是协议类,即能被单独编解码的协议类对象。而枚举值是不能被单独编解码的,这点可使用原生 proto 尝试。