1.下载与安装

  官方网站:http://msgpack.org/

  下载地址:https://github.com/msgpack/msgpack-rpc, https://github.com/msgpack/msgpack

  安装之前确保已经装了git和maven

  1. cd /usr/local/src
  2. mkdir msgpack
  3. cd msgpack
  4. git clone git://github.com/msgpack/msgpack.git
  5. git clone git://github.com/msgpack/msgpack-rpc.git
  6. cd msgpack/java
  7. mvn package
  8. cd ../../msgpack-rpc/java
  9. mvn package

  安装成功后,将会在msgpack/msgpack/java/target目录中生成msgpack-0.*.*-devel.jar,会在msgpack/msgpack-rpc/java/target目录中生成msgpack-rpc-0.*.*-devel.jar

2.消息结构与服务接口

  定义消息类比较简单,只需要给类加上注解@MessagePackMessage即可。

  另一种不添加注解的方法是对类进行注册,如下所示:

  1. // You register your class before use.
  2. MessagePack.register(MyClass.class);

3.序列化

  MessagePack在序列化数据中保存类型信息,每个数据以*type-data*或*type-length-data*模式存储。

  MessagePack支持以下类型:

    定长类型:

      Integers:

      Nil:

      Boolean:

      Floating point:

    变长类型:

      Raw bytes:

    容器类型:

      Arrays:

      Maps:

  每种类型有一或多个序列化格式。

3.1.Integer

  positive fixnum:用1个字节保存一个整数,数值范围为[0,127]。

  1. |0XXXXXXX|
  2. => unsigned 8-bit 0XXXXXXX

  negative fixnum:用1个字节保存一个整数,数值范围为[-32,-1]。

  1. |111XXXXX|
  2. => signed 8-bit 111XXXXX

  uint8:用2个字节保存一个8位的unsigned integer。

  1. |  0xcc  |XXXXXXXX|
  2. => unsigned 8-bit XXXXXXXX

  uint16:用3个字节保存一个16位的unsigned integer。

  1. |  0xcd  |XXXXXXXX|XXXXXXXX|
  2. => unsigned 16-bit big-endian XXXXXXXX_XXXXXXXX

  uint32:用5个字节保存一个32位的unsigned integer。

  1. |  0xce  |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|
  2. => unsigned 32-bit big-endian XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX

  uint64:用9个字节保存一个64位的unsigned integer。

  1. |  0xcf  |XXXXXXXX| XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX |
  2. => unsigned 64-bit big-endian XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX

  int8:用2个字节保存一个8位的signed integer。

  1. |  0xd0  |XXXXXXXX|
  2. => signed 8-bit XXXXXXXX

  int16:用3个字节保存一个16位的signed integer。

  1. |  0xd1  |XXXXXXXX|XXXXXXXX|
  2. => signed 16-bit big-endian XXXXXXXX_XXXXXXXX

  int32:用5个字节保存一个32位的signed integer。

  1. |  0xd2  |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|
  2.   => signed 32-bit big-endian XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX

  int64:用9个字节保存一个64位的signed integer。

  1. |  0xd3  |XXXXXXXX| XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX |
  2. => signed 64-bit big-endian XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX

3.2.Nil

  1. |  0xc0  |

3.3.Boolean

  true:

  1. |  0xc3  |

  false:

  1. |  0xc2  |

3.4.Floating point

  float:用5个字节保存。

  1. |  0xca  |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|
  2. => big-endian IEEE 754 single precision floating point number XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX

  double:用9个字节保存。

  1. |  0xcb  |XXXXXXXX| XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX |
  2. => big-endian IEEE 754 single precision floating point number XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX _ XXXXXXXX

3.5.Raw bytes

  fix raw:最多保存31个字节。

  1. |101XXXXX|...N bytes
  2. => 000XXXXXX (=N) bytes of raw bytes.

  raw 16:最多保存(2^16)-1个字节,长度以unsigned 16-bit big-endian integer存储。

  1. |  0xda  |XXXXXXXX|XXXXXXXX|...N bytes
  2. => XXXXXXXX_XXXXXXXX (=N) bytes of raw bytes.

  raw 32:最多保存(2^32)-1个字节,长度以unsigned 32-bit big-endian integer存储。

  1. |  0xdb  |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|...N bytes
  2. => XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX (=N) bytes of raw bytes.

3.6.Arrays

  fix array:最多保存15个元素。

  1. |1001XXXX|...N objects
  2. => 0000XXXX (=N) elements array.

  array 16:最多保存 (2^16)-1个元素,元素的数量以unsigned 16-bit big-endian integer存储。

  1. |  0xdc  |XXXXXXXX|XXXXXXXX|...N objects
  2. => XXXXXXXX_XXXXXXXX (=N) elements array.

  array 32:最多保存 (2^32)-1个元素,元素的数量以unsigned 32-bit big-endian integer存储。

  1. |  0xdd  |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|...N objects
  2. => XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX (=N) bytes of raw bytes.

3.7.Maps

  fix map:最多保存15个元素。

  1. |1000XXXX|...N*2 objects
  2. => 0000XXXX (=N) elements map
  3.    where odd elements are key and next element of the key is its associate value.

  map16:最多保存 (2^16)-1个元素,元素的数量以unsigned 16-bit big-endian integer存储。

  1. |  0xde  |XXXXXXXX|XXXXXXXX|...N*2 objects
  2. => XXXXXXXX_XXXXXXXX (=N) elements map
  3.    where odd elements are key and next element of the key is its associate value.

  map32:最多保存 (2^32)-1个元素,元素的数量以unsigned 32-bit big-endian integer存储。

  1. |  0xdf  |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX|...N*2 objects
  2. => XXXXXXXX_XXXXXXXX_XXXXXXXX_XXXXXXXX (=N) elements map
  3.    where odd elements are key and next element of the key is its associate value.

4.rpc通信实现

  定义消息Message.java:

  1. package msgpack;
  2.  
  3. import org.msgpack.annotation.MessagePackMessage;
  4.  
  5. @MessagePackMessage
  6. public class Message {
  7.     // some attributes
  8. }

  服务端实现Server.java:

  1. package msgpack;
  2.  
  3. import org.msgpack.rpc.loop.EventLoop;
  4.  
  5. public class Server {
  6.     private int port;
  7.  
  8.     public Server(int port) {
  9.         this.port = port;
  10.     }
  11.  
  12.     public Message getMessage(Message msg) {
  13.     // process request
  14.         …
  15.         return msg;
  16.     }
  17.    
  18.     public void run() {
  19.         try {
  20.             EventLoop loop = EventLoop.defaultEventLoop();
  21.             
  22.             org.msgpack.rpc.Server svr = neworg.msgpack.rpc.Server();
  23.             svr.serve(new Server(port));
  24.             svr.listen(port);
  25.     
  26.             loop.join();
  27.         } catch (Exception e) {
  28.             e.printStackTrace();
  29.         }
  30.     }
  31.  
  32.     public static void main(String[] args) {
  33.         if (args.length != 1) {
  34.             System.out.println("Usage: Server port");
  35.             return;
  36.         }
  37.  
  38.         int port = Integer.parseInt(args[0]);
  39.  
  40.         new Server(port).run();
  41.     }
  42. }

  客户端实现Client.java:

  1. package msgpack;
  2.  
  3. import java.util.Arrays;
  4. import org.msgpack.rpc.loop.EventLoop;
  5.  
  6. public class Client {
  7.     private int port;
  8.     private String host;
  9.     private int size;
  10.     private int count;
  11.    
  12.     public static interface RPCInterface {
  13.         Message getMessage(Message msg);
  14.     }
  15.  
  16.     public Client(int portString hostint sizeint count){
  17.         super();
  18.         this.port = port;
  19.         this.host = host;
  20.         this.size = size;
  21.         this.count = count;
  22.     }
  23.  
  24.     public long run() {
  25.         long start = 0;
  26.         long end = 0;
  27.         try {
  28.             EventLoop loop = EventLoop.defaultEventLoop();
  29.             
  30.             org.msgpack.rpc.Client client = neworg.msgpack.rpc.Client(hostportloop);
  31.             RPCInterface iface =client.proxy(RPCInterface.class);
  32.     
  33.             Message msg = new Message();
  34.             // initiate message
  35.             …
  36.            
  37.             start = System.currentTimeMillis();
  38.             for (int i = 0 ; i < count;i++) {
  39.                 iface.getMessage(msg);
  40.             }
  41.             end = System.currentTimeMillis();
  42.             System.out.println(end - start);
  43.            
  44.             client.close();
  45.             loop.shutdown();
  46.         } catch (Exception e) {
  47.             e.printStackTrace();
  48.         }
  49.         return end - start;
  50.     }
  51.  
  52.     public static void main(String[] args) {
  53.         if (args.length != 4) {
  54.             System.out.println("Usage: Client host port dataSize count");
  55.             return;
  56.         }
  57.         String host = args[0];
  58.         int port = Integer.parseInt(args[1]);
  59.         int size = Integer.parseInt(args[2]);
  60.         int count = Integer.parseInt(args[3]);
  61.  
  62.         new Client(porthostsizecount).run();
  63.     }
  64. }

5.参考资料

  (1) MessagePack QuickStart for Java:http://wiki.msgpack.org/display/MSGPACK/QuickStart+for+Java

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐