Darks Codec
===========
Darks codec is a lightweight message protocol encoding and decoding framework.
It supports encoding and decoding message object of most message protocol based on bytes.
It helps developers build any message protocol easily and quickly.
And help to solve network communication protocol TCP's stick package and broken package problem.
It makes developers design attention more than the implementation of message protocol, which can help software design better.
Simple Example
-----------
### Define Message Structure
If we want to build the message protocol with LITTLE-ENDIAN like:
<pre>
FB FA [ID 32bits] [VERSION 8bits] [COMMAND] FF
</pre>
We can build JAVA class like:
<pre>
public class SimpleMsg
{
int id;
byte version;
String command;
}
</pre>
In order to describe simple, we omit get/set method.
### Configure Object Coder
According to message protocol, we only need Head identify "FB FA" and tail identify "FF" besides message body, so we can configure object coder like:
<pre>
ObjectCoder coder = new ObjectCoder();
coder.getCodecConfig().setEndianType(EndianType.LITTLE);
coder.getCodecConfig().addWrap(new IdentifyWrapper(new OCInt16(0xFAFB), new OCInt8(0xFF)));
</pre>
### Encoding Message
Now we can encode message object easily.
<pre>
SimpleMsg msg = new SimpleMsg();
msg.id = 32;
msg.version = 1;
msg.command = "running";
byte[] bytes = coder.encode(msg);
System.out.println(ByteHelper.toHexString(bytes));
</pre>
Code will output console information:
<pre>
FB FA 20 00 00 00 01 72 75 6E 6E 69 6E 67 FF
</pre>
Because of LITTLE-ENDIAN, 0xFAFB coded as "FB FA", ID which is 32 coded as "20 00 00 00", VERSION which is 1 coded as "01",
command which is "running" coded as "72 75 6E 6E 69 6E 67" and 0xFF coded as "FF".
### Decoding Message
Now we try to decode message object easily.
<pre>
SimpleMsg result = new SimpleMsg();
coder.decode(bytes, result);
System.out.println("ID:" + result.id);
System.out.println("VERSION:" + result.version);
System.out.println("COMMAND:" + result.command);
</pre>
Code will output console information:
<pre>
ID:32
VERSION:1
COMMAND:running
</pre>
### Total Length
Some message protocol need replace tail identify with bytes total length.
We can set total length type to have the bytes total length. Total length type have AUTO, BODY and HEAD_BODY types.<br/>
AUTO : Automatic object total length. It calculate object length without head or tail wrapper's length only when autoLength is true.<br/>
BODY : Body total length will calculate object length and tail wrapper's length without head wrapper's length.<br/>
HEAD_BODY : Head and body total length will calculate head wrapper, tail wrapper and object length.<br/>
<pre>
ObjectCoder coder = new ObjectCoder();
coder.getCodecConfig().setEndianType(EndianType.LITTLE);
coder.getCodecConfig().setTotalLengthType(TotalLengthType.HEAD_BODY);
coder.getCodecConfig().addWrap(new IdentifyWrapper(new OCInt16(0xFAFB)));
</pre>
Code will output console information:
<pre>
FB FA 12 00 00 00 20 00 00 00 01 72 75 6E 6E 69 6E 67
</pre>
Now, we have finished a simple example. You can find codes in /examples/darks/codec/examples/simple.
Automatic Value Length
-----------------------
If message protocol have multiply object type such as String, Object, Bytes and so on,
we should set automatic length to ensure decoding message correctly.<br/>
Message protocol may like:
<pre>
FB FA [TOTAL LENGTH] [ID 32bits] [VERSION 8bits] [CMD1 LEN 32bits] [COMMAND1] [CMD2 LEN 32bits] [COMMAND2]
</pre>
Java bean class:
<pre>
public class MultiCmdMsg
{
int id;
byte version;
String command1;
String command2;
}
</pre>
Then we encode it object will automatic length:
<pre>
ObjectCoder coder = new ObjectCoder();
coder.getCodecConfig().setEndianType(EndianType.LITTLE);
coder.getCodecConfig().setTotalLengthType(TotalLengthType.HEAD_BODY);
coder.getCodecConfig().setAutoLength(true);
coder.getCodecConfig().addWrap(new IdentifyWrapper(new OCInt16(0xFAFB)));
MultiCmdMsg msg = new MultiCmdMsg();
msg.id = 32;
msg.version = 1;
msg.command1 = "ready";
msg.command2 = "running";
byte[] bytes = coder.encode(msg);
System.out.println(ByteHelper.toHexString(bytes));
</pre>
Code will output console information:
<pre>
FB FA 1F 00 00 00 20 00 00 00 01 05 00 00 00 72 65 61 64 79 07 00 00 00 72 75 6E 6E 69 6E 67
</pre>
You can see detail example codes in /examples/darks/codec/examples/autolen.
Codec Type
-------------
Besides using JAVA type directly, developers can use codec type which is in package darks.codec.type more flexibly to code.<br/>
OCInt32 : 32-bits integer type which based on OCInteger.<br/>
OCInt16 : 16-bits integer type which based on OCInteger.<br/>
OCInt8 : 8-bits integer type which based on OCInteger.<br/>
OCLong : 64-bits long type.<br/>
OCFloat : Just like float.<br/>
OCDouble: Just like double.<br/>
OCBytes : Bytes array type.<br/>
OCString: Just like String.<br/>
OCList : It can store collection data which based on java.util.List.<br/>
OCMap : It can store Key-value pair values which based on java.util.Map.<br/>
OCListMap: It can store multiply values in same key index besides Map feature.<br/>
OCObject: Java object can extends it to code flexibly.<br/>
Custom Type: Developers can build a class which inherit from OCBase or OCBaseType to customize type, which must add annotation @CodecType.<br/>
### Codec Type Example
We can rebuild SimpleMsg by codec type.
<pre>
public class SimpleMsg extends OCObject
{
OCInt32 id = new OCInt32();
OCInt8 version = new OCInt8();
OCString command = new OCString();
}
</pre>
Also we can rebuild MultiCmdMsg by mix type.
<pre>
public class MultiCmdMsg
{
int id;
byte version;
OCInt32 cmdLen1 = new OCInt32();
OCString command1 = new OCString(cmdLen1);
OCInt32 cmdLen2 = new OCInt32();
OCString command2 = new OCString(cmdLen2);
}
</pre>
"command1 = new OCString(cmdLen1)" can set command1's length value to field "cmdLen1" automatically.
And It will decode command1 by cmdLen1's value when decoding. Therefore we should set parameter "autoLength" false.
<pre>
ObjectCoder coder = new ObjectCoder();
coder.getCodecConfig().setEndianType(EndianType.LITTLE);
coder.getCodecConfig().setTotalLengthType(TotalLengthType.HEAD_BODY);
coder.getCodecConfig().setAutoLength(false); //default false.
coder.getCodecConfig().addWrap(new IdentifyWrapper(new OCInt16(0xFAFB)));
MultiCmdMsg msg = new MultiCmdMsg();
msg.id = 32;
msg.version = 1;
msg.command1.setValue("ready");
msg.command2.setValue("running");
byte[] bytes = coder.encode(msg);
System.out.println(ByteHelper.toHexString(bytes));
</pre>
You can see detail example codes in /examples/darks/codec/examples/codectype.
Complex Message
--------------
We can try to build a multiple nested object. The message protocol just like:
<pre>
FA FB [TOTAL LEN 32bits] [ID 32bits] [VERSION 8bits] [EXTERN LEN 16bits] [EXTERN BYTES] [SUB LEN 32 bits] [#SUB MSG#[CODE LEN 8bits] [CODE] [MODULAR 8bits] [SUB MODULAR 8bits] [#CMDS#[CMD CODE 8bits] [CODE length 16bits] [CODE] ... [CMD CODE 8bits] [CODE length 16bits] [CODE]]]
</pre>
We can build JAVA bean like:
<pre>
public class ComplexMsg
{
int id;
byte version;
OCInt16 externLength = new OCInt16();
OCBytes extern = new OCBytes(externLength);
OCInt32 subMsgLength = new OCInt32();
ComplexSubMsg subMsg = new ComplexSubMsg(subMsgLength);
}
class ComplexSubMsg extends OCObject
{
OCInt8 codeLen = new OCInt8();
OCString equipCode = new OCString(codeLen);
byte
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
Dubbo作为Java语言的RPC框架,优势之一在于屏蔽了调用细节,能够像调用本地方法一样调用远程服务,不必为数据格式抓耳饶腮。正是这一特性,也引入来了一些问题。 比如引入facade包后出现jar包冲突、服务无法启动,更新facade包后某个类找不到等等问题。引入jar包,导致消费方和提供方在某种程度上有了一定耦合。 正是这种耦合,在提供者修改了Facade包类的路径后,习惯性认为会引发报错,而实际上并没有。最初认为很奇怪,仔细思考后才认为理应这样,调用方在按照约定的格式和协议基础上,即可与提供方完成通信。并不应该关注提供方本身上下文信息。(认为类的路径属于上下文信息)接下来揭秘Dubbo的编码解码过程。
资源推荐
资源详情
资源评论




















收起资源包目录





































































































共 438 条
- 1
- 2
- 3
- 4
- 5
资源评论


野生的狒狒
- 粉丝: 88
- 资源: 1067
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


安全验证
文档复制为VIP权益,开通VIP直接复制
