diff --git a/protocol/src/main/java/com/zfoo/protocol/ProtocolManager.java b/protocol/src/main/java/com/zfoo/protocol/ProtocolManager.java index 47a8f4e0..80939e6e 100644 --- a/protocol/src/main/java/com/zfoo/protocol/ProtocolManager.java +++ b/protocol/src/main/java/com/zfoo/protocol/ProtocolManager.java @@ -123,6 +123,12 @@ public class ProtocolManager { ProtocolAnalysis.analyze(protocolClassSet, GenerateOperation.NO_OPERATION); } + /** + * 注册协议:将协议id和对应的协议信息关联起来 + * + * @param protocolClassSet 需要初始化的协议列表 + * @param generateOperation 协议配置:需要生成哪些语言的协议文件 是否折叠等信息 + */ public static void initProtocol(Set> protocolClassSet, GenerateOperation generateOperation) { ProtocolAnalysis.analyze(protocolClassSet, generateOperation); } diff --git a/protocol/src/main/java/com/zfoo/protocol/generate/GenerateProtocolPath.java b/protocol/src/main/java/com/zfoo/protocol/generate/GenerateProtocolPath.java index 8856a0f0..aec46319 100644 --- a/protocol/src/main/java/com/zfoo/protocol/generate/GenerateProtocolPath.java +++ b/protocol/src/main/java/com/zfoo/protocol/generate/GenerateProtocolPath.java @@ -54,6 +54,10 @@ public abstract class GenerateProtocolPath { } public static String getRelativePath(short protocolId, short relativeProtocolId) { + // 不是折叠协议的话,protocolPathMap一定是空,这里返回“”,上层会解析为同一个文件下 + if(protocolPathMap.size() == 0){ + return ""; + } var protocolPath = protocolPathMap.get(protocolId); var relativePath = protocolPathMap.get(relativeProtocolId); if (relativePath.startsWith(protocolPath)) { diff --git a/protocol/src/main/java/com/zfoo/protocol/registration/ProtocolAnalysis.java b/protocol/src/main/java/com/zfoo/protocol/registration/ProtocolAnalysis.java index 0bc304b6..d4925f62 100644 --- a/protocol/src/main/java/com/zfoo/protocol/registration/ProtocolAnalysis.java +++ b/protocol/src/main/java/com/zfoo/protocol/registration/ProtocolAnalysis.java @@ -89,16 +89,26 @@ public class ProtocolAnalysis { baseSerializerMap.put(String.class, StringSerializer.INSTANCE); } + /** + * 真正的注册协议,将协议id和协议信息关联起来 + * + * @param protocolClassSet + * @param generateOperation + */ public static synchronized void analyze(Set> protocolClassSet, GenerateOperation generateOperation) { AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,请不要重复初始化", ProtocolManager.class.getSimpleName()); try { + // 检查协议类是否合法 for (var protocolClass : protocolClassSet) { checkProtocol(protocolClass); } + + // 协议id和协议信息对应起来 for (var protocolClass : protocolClassSet) { var registration = parseProtocolRegistration(protocolClass, ProtocolModule.DEFAULT_PROTOCOL_MODULE); protocols[registration.protocolId()] = registration; } + // 通过指定类注册的协议,全部使用字节码增强 var enhanceList = Arrays.stream(protocols).filter(it -> Objects.nonNull(it)).collect(Collectors.toList()); enhance(generateOperation, enhanceList); diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/reflect/ISerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/reflect/ISerializer.java index df272e3e..524ccd13 100644 --- a/protocol/src/main/java/com/zfoo/protocol/serializer/reflect/ISerializer.java +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/reflect/ISerializer.java @@ -22,6 +22,13 @@ import io.netty.buffer.ByteBuf; */ public interface ISerializer { + /** + * 往buffer中写入这个值是多少,及其反序列化时要用的解析类型是啥 + * + * @param buffer buffer缓冲区,存储二进制数控 + * @param object 要写入到buffer中的对象 + * @param fieldRegistration 标记下反序列化时读取这个值要用啥类型方式读取 + */ void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration); Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration); diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/reflect/MapSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/reflect/MapSerializer.java index 4af73866..f6d0779c 100644 --- a/protocol/src/main/java/com/zfoo/protocol/serializer/reflect/MapSerializer.java +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/reflect/MapSerializer.java @@ -41,6 +41,7 @@ public class MapSerializer implements ISerializer { Map map = (Map) object; MapField mapField = (MapField) fieldRegistration; + // map有几组key、value int size = map.size(); if (size == 0) { ByteBufUtils.writeInt(buffer, 0); @@ -48,6 +49,7 @@ public class MapSerializer implements ISerializer { } ByteBufUtils.writeInt(buffer, size); + // buffer中顺序写入 for (Map.Entry entry : map.entrySet()) { mapField.getMapKeyRegistration().serializer().writeObject(buffer, entry.getKey(), mapField.getMapKeyRegistration()); diff --git a/protocol/src/test/java/com/zfoo/protocol/SpeedTest.java b/protocol/src/test/java/com/zfoo/protocol/SpeedTest.java index 03f61c9d..399e8ac6 100644 --- a/protocol/src/test/java/com/zfoo/protocol/SpeedTest.java +++ b/protocol/src/test/java/com/zfoo/protocol/SpeedTest.java @@ -23,6 +23,7 @@ import com.google.protobuf.CodedOutputStream; import com.zfoo.protocol.collection.ArrayUtils; import com.zfoo.protocol.generate.GenerateOperation; import com.zfoo.protocol.packet.*; +import com.zfoo.protocol.serializer.CodeLanguage; import com.zfoo.protocol.util.StringUtils; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; @@ -67,6 +68,7 @@ public class SpeedTest { protobufTest(); kryoTest(); + // 递归执行,多跑几遍 benchmark = benchmark * 2; singleThreadBenchmarks(); } @@ -105,7 +107,10 @@ public class SpeedTest { long startTime = System.currentTimeMillis(); for (int i = 0; i < benchmark; i++) { buffer.clear(); + // 把对象序列化到buffer中 ProtocolManager.write(buffer, simpleObject); + + // 从buffer中反序列化出对象 var packet = ProtocolManager.read(buffer); } @@ -298,8 +303,12 @@ public class SpeedTest { static { var op = GenerateOperation.NO_OPERATION; -// op.getGenerateLanguages().add(CodeLanguage.JavaScript); - // zfoo协议注册 + + // 这行加上,会在protocol目录下,生成jsProtocol文件夹及其对应的js协议文件 + op.getGenerateLanguages().add(CodeLanguage.JavaScript); + op.getGenerateLanguages().add(CodeLanguage.TypeScript); + + // zfoo协议注册(其实就是:将Set里面的协议号和对应的类注册好,这样子就可以根据协议号知道是反序列化为哪个类) ProtocolManager.initProtocol(Set.of(ComplexObject.class, NormalObject.class, SimpleObject.class, ObjectA.class, ObjectB.class), op); for (int i = 0; i < executors.length; i++) { @@ -308,6 +317,7 @@ public class SpeedTest { } // -------------------------------------------以下为测试用例--------------------------------------------------------------- + // 简单类型 private static final byte byteValue = 99; private static final short shortValue = 9999; private static final int intValue = 99999999; @@ -318,7 +328,7 @@ public class SpeedTest { private static final String charValueString = "c"; private static final String stringValue = "hello"; - + // 数组类型 private static final boolean[] booleanArray = new boolean[]{true, false, true, false, true}; private static final byte[] byteArray = new byte[]{Byte.MIN_VALUE, -99, 0, 99, Byte.MAX_VALUE}; private static final short[] shortArray = new short[]{Short.MIN_VALUE, -99, 0, 99, Short.MAX_VALUE}; @@ -586,16 +596,24 @@ public class SpeedTest { } + /** + * 简单和复杂对象的序列化和反序列化测试,这个其实是基于ProtoManager.initProtocol初始化协议后执行的 + */ @Test public void cmEnhanceMessTest() { var buffer = new UnpooledHeapByteBuf(ByteBufAllocator.DEFAULT, 100, 1_0000); - // 序列化和反序列化简单对象 + // 简单对象序列化和反序列化测试 + // 序列化:把normalObject序列化一下写到buffer中 ProtocolManager.write(buffer, normalObject); + // 反序列化:从buffer中反序列化为协议包 var packet = ProtocolManager.read(buffer); + buffer.clear(); + // 复杂对象序列化和反序列化测试 ProtocolManager.write(buffer, complexObject); packet = ProtocolManager.read(buffer); + buffer.clear(); } }