-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
探讨消息注册 #33
Comments
不会的,这里第一次只解析了消息头, |
老哥,新版本已经包含消息注册的功能,参考 |
测试用例有点问题,修改一下呢 |
不好意思,不太会用 github,没找到像 gitlab 那种标记未就绪的合并请求的功能。
其实,我是想这么用: @MagicClass
public class Protocol implements MConverter<MagicMessage> {
@MagicField(order = 1)
private Head head;
@MagicField(order = 3)
@MagicConverter(converter = Protocol.class)
private MagicMessage body;
} 这样我就可以统一返回一个 protocol 对象,然后相应的业务直接 getBody 就可以拿走用了,如果是示例代码那种,body 对象里放 Head 就感觉有点儿乱 |
可以这么理解,消息头是公用的,也就是所有消息都有消息头。 消息整体 = 消息头+消息体。 你拿一个body,本身就只是消息的一部分,不算完整消息的 |
也就是每个消息都是独立体,共同体是消息头。 而你这个思路是,所有消息都是共同体,共享一个消息头。你这个自定义个序列化也可以实现。 |
你这里的思路,需要重新定义一个接口,然后自定义实现解析。也是可以实现的。 |
|
是不是更像是 wiki 数据实体定义的最佳实践的 2: 自行解析数据和代码 这部分; 我刚才思考了一下咱们这个框架的逻辑,其实注册的 registerCMD 的 msgClazz 不一定要有cmdField = true,只要我实现了接口的 cmd 方法就可以知道这个实现类的 cmd 号了。然后就可以在 cache 建立号与类的映射关系,然后 pack 方法在反序列化我上面那个 Protocol 的时候我使用 而上述这个在操作的时候有个问题在于,现在通过注册的方式既获取了 cmd 号又知道了 cmd 在二进制数据里的长度与位置,但是这个 cmd 位置信息其实可以通过单独注册位置的方式来进行或者通过注解扫描的形式注册 |
那我如果不写 Convert 为啥序列化成二进制的时候只序列化了 Head 没序列化 body 呢? |
因为这个 |
目前版本我要用是不是更像是 wiki 数据实体定义的最佳实践的 2: 自行解析数据和代码 这部分? 我刚才思考了一下咱们这个框架的逻辑,其实注册的 registerCMD 的 msgClazz 不一定要有cmdField = true,只要我实现了接口的 cmd 方法就可以知道这个实现类的 cmd 号了。然后就可以在 cache 建立号与类的映射关系,然后 pack 方法在反序列化我上面那个 Protocol 的时候我使用 MagicByte.pack(bytes, Protocol.class); 但是到,body 属性的时候发现他是 MagicMessage 再取 cmd 值找到对应类型做反序列化。 而上述这个在操作的时候有个问题在于,现在通过注册的方式既获取了 cmd 号又知道了 cmd 在二进制数据里的长度与位置,但是这个 cmd 位置信息其实可以通过单独注册位置的方式来进行或者通过注解扫描的形式注册 |
|
但是目前看起来并没有从简,接口类也没有任何注释,wiki 示例里也没有对实现 cmd 方法有什么描述,什么时候该用,怎么用;目前来看整体的灵活性也不足,限制颇多,没法注册多个 cmd 的偏移。而且,样例代码里的写法是写死的,也容易让人被误解。而且,实际上测试用例里有的我把重写的 cmd 方法删了也不会有任何问题。但有的就会出现 -1 导致反序列化为 null 的结果。所以我建议配置哪个字段是 cmd 不如直接设置全局的 cmd 的长度和偏移位置,甚至这样还可以设置多种 cmd 的情况。然后 cmd() 方法就是类似策略模式,用于匹配对应的对象,这样也会很简单 |
|
|
|
@MagicClass
public class Protocol implements MConverter<MagicMessage>, MagicMessage {
@MagicField(order = 1)
private Head head;
@MagicField(order = 3)
private MagicMessage body;
} 注册的是 MagicMessage 实现类,这样二进制数据过来的时候依旧可以从数据里拿到对应位置的 cmd 值,然后用 pack(byte[], clazz) 的方法解析的时候判断到属性类型是 MagicMessage 就去注册里找我注册对应 cmd 值的实现类,这样就可以实现动态 body 内容了 |
|
标记的目的时为了获取消息类型的偏移量和值 |
那目前其实就是这个问题:如果我是这么封装的 @MagicClass
public class Protocol implements MagicMessage {
@MagicField(order = 1)
private Head head;
@MagicField(order = 3)
private MagicMessage body;
} 而且,注册的时候把 cmdField 检查去了,我可以用 |
现在是把每条消息当作一个独立的整体进行解析,他们有一个共同的模板 没有实质性的区别的。 |
而且比起将模板交给开发者来定义,不如交给开发者开标准。这样更容易上手。 实现一个接口,和使用这个接口当作属性。肯定是前者更简单啊 |
|
没有的,自能自己实现类似的效果 |
那不就是我推上去那个测试例子的效果? |
可以的 |
我那个代码还有优化改造的空间吗? |
Head pack = MagicByte.pack(deviceUploadMessage, Head.class);
,然后HeartbeatCmd pack1 = MagicByte.pack(deviceUploadMessage, HeartbeatCmd.class);
用同一个二进制数据从头开始解析,数据结果是不对的,因为需要偏移起始位置,但是又要先获得 Head 的全长再去偏移生成对象,比较繁琐The text was updated successfully, but these errors were encountered: