本人为游戏服务端开发者,开发中protobuf的解码操作比较麻烦,每次解码都需要写一大堆重复的代码,还需要处理错误,设计了一个工具类,现在将业务逻辑简化一下和除去业务敏感信息,发布出来,使用源码需要注意以下几点:
1.所有protobuf 消息基于 generatedMessage;
2.protobuf运行时需要配置protobuf.exe位置
3.反射比较耗费性能,设计中将反射等操作放在系统初始化进行,将结果放置到map中,业务运行时直接取出;.
4.开发中结合注解还能进一步简化配置,不需要添加class 到map中
5.对于编码错误,可能为第三方恶意尝试命令码,编码错误统一管理更加方便屏蔽.
解码代码如下:
package code; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import proto.gen.TestProto.MyMsgReq; import com.google.protobuf.GeneratedMessage; public class DecordDemo { private final static Map<Integer, Method> DECODE_METHODS_MAP = new HashMap<Integer, Method>();// 存储解码方法MAP private final static Map<Integer, Class<? extends GeneratedMessage>> DECODE_CLASSES = new HashMap<Integer, Class<? extends GeneratedMessage>>();// 存储类的map private final static int MY_MSG_REQ_CMD = 100; public static void main(String[] args) throws Exception { initDecode(); MyMsgReq.Builder reqSrc = MyMsgReq.newBuilder().setId(1).setName("mine"); MyMsgReq req = decode(MY_MSG_REQ_CMD, reqSrc.build().toByteArray()); System.out.println(req.getId()); System.out.println(req.getName()); } /** * 初始化 方法,系统启动时即将解码器反射好,业务逻辑时直接从MAP中查询出,解码 * */ public static void initDecode() { addDecodeMethod(MY_MSG_REQ_CMD, MyMsgReq.class); } public static void addDecodeMethod(int cmd, Class<? extends GeneratedMessage> clazz) { try { Method m = clazz.getMethod("parseFrom", new Class[] { byte[].class }); if (DECODE_METHODS_MAP.get(cmd) == null) { DECODE_METHODS_MAP.put(cmd, m); } if (DECODE_CLASSES.get(cmd) == null) { DECODE_CLASSES.put(cmd, clazz); } } catch (NoSuchMethodException | SecurityException e) { e.printStackTrace(); } } /** * 业务中调用 * * @throws Exception * */ @SuppressWarnings("unchecked") public static <T> T decode(int cmd, byte[] data) throws Exception { Method decodeMethod = DECODE_METHODS_MAP.get(cmd); Class<? extends GeneratedMessage> clazz = DECODE_CLASSES.get(cmd); if (decodeMethod == null || clazz == null) { throw new Exception("找不到对应解码方法"); } T req; try { req = (T) decodeMethod.invoke(clazz, new Object[] { data }); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); throw new Exception("解码异常", e); } return req; } } protobuf代码如下:
package proto.gen; message MyMsgReq { required int32 id = 1; optional string name = 2; // }
相关推荐
protobufDemo protobuf例程protobufDemo protobuf例程protobufDemo protobuf例程protobufDemo protobuf例程protobufDemo protobuf例程protobufDemo protobuf例程protobufDemo protobuf例程
自定义Protobuf的编解码器,和官方的只能发送一个消息格式比较,能发送多个protobuf对象,protobuf文件夹下有生成protobuf的工具和使用说明
protoBuf Java语言使用demo
protobuf demo 接口当中使用protobuf 主要内容请查看博客https://blog.csdn.net/qq_21113625/article/details/103782738
protoc(Protobuf解码解密工具)用于无原始类时反编译数据,结构分析。 Probobuf反序列化工具,2020-07-21实测好用,内含使用示例。 包含proboc.exe
Unity 中使用Protobuf进行序列化和反序列化的Demo
Google protobuf 协议测试demo程序 probufTest.tar.gz,使用Intellij idea开发。
spring boot protobuf demo
protobuf 自动生成c# .cs文件。。。内附使用说明。protobuf 自动生成c# .cs文件。。。内附使用说明。
protobuf完整demo 包含静态链接库 libprotobuf.lib 、libprotoc.lib、protoc.exe等。 以及对应源码,新人直接使用demo就可以了,省去了麻烦的编译过程。 请注意修改包含文件路径和包含库路径。 直接使用VS2017 ...
protobuf-netty-Demo
Unity与Java使用ProtoBuf通信的Demo 代码可以直接使用
NULL 博文链接:https://shihuan830619.iteye.com/blog/2265589
protobuf-net将JSON文件压缩与解压缩示例代码,包含protobuf-net.dll和Newtonsoft.Json.dll的使用方法
使用.proto 数据格式demo
protobuf2测试demo与所需lib、exe.使用了Qt创建工程。可以转为vs工程。
支持google的编解码protobuf框架自动生成代码的工具类
protobuf 命名空间,包