MessagePack 学习笔记
封装和解析类似json的 key-value 示例
{"ID" = 333,"name"="zds","3333"="ende"}
msgpack::sbuffer sBuf;
msgpack::packer<msgpack::sbuffer> pker(&sBuf); pker.pack_map();
pker.pack(std::string("ID"));
pker.pack();
pker.pack(std::string("name"));
pker.pack(std::string("zds"));
pker.pack(std::string(""));
pker.pack(std::string("ende")); //unserilized
msgpack::unpacked unpack;
msgpack::unpack(unpack, sBuf.data(), sBuf.size()); msgpack::object obj = unpack.get();
std::cout << obj << std::endl; if (obj.type == msgpack::type::ARRAY)
std::cout << "是array" << std::endl;
else if (obj.type == msgpack::type::MAP)
std::cout << "是map" << std::endl; if(obj.via.map.size > )
{
auto pkv = obj.via.map.ptr;
auto pkv_end = obj.via.map.ptr + obj.via.map.size; do
{
auto key = pkv->key;
auto val = pkv->val;
std::cout << "key:" << key << " value:" << val << std::endl;
++pkv;
} while (pkv < pkv_end);
}
解析Socket示例
各类数据结构:
msgpack::object 他是一个引用,拷贝他的代价少,因为他是浅拷贝
msgpack::object_handle 他管理了一个对象的生命周期。他如果释放了,所有从他生成的object都是无效的引用
解析Socket示例
下列代码解析socke收包数据
unpacker.reserve_buffer 分配要收的数据的内存字节数
unpacker..buffer() 返回数据地址
unpacker.buffer_consumed() 设置实际收到的数据
unpacker.next(object_handle& oh) 循环解析数据
int main() {
boost::asio::io_service ios;
std::uint16_t const port = ;
// Server
std::size_t const window_size = ;
boost::asio::ip::tcp::acceptor ac(ios, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port));
boost::asio::ip::tcp::socket ss(ios);
std::function<void()> do_accept;
std::function<void()> do_async_read_some;
msgpack::unpacker unp;
do_accept = [&] {
ac.async_accept(
ss,
[&]
(boost::system::error_code const& e) {
if (e) {
std::cout << __LINE__ << ":" << e.message() << std::endl;
return;
}
unp.reserve_buffer(window_size);
do_async_read_some = [&] {
ss.async_read_some(
boost::asio::buffer(unp.buffer(), window_size),
[&](boost::system::error_code const& e, std::size_t bytes_transferred) {
if (e) {
std::cout << __LINE__ << ":" << e.message() << std::endl;
return;
}
std::cout << bytes_transferred << " bytes read." << std::endl;
unp.buffer_consumed(bytes_transferred);
msgpack::object_handle oh;
while (unp.next(oh)) {
std::cout << oh.get() << std::endl;
// In order to finish the program,
// return if one complete msgpack is processed.
// In actual server, don't return here.
return;
}
do_async_read_some();
}
);
};
do_async_read_some();
}
);
};
do_accept();
// Client
auto host = "localhost";
boost::asio::ip::tcp::resolver r(ios);
boost::asio::ip::tcp::resolver::query q(host, boost::lexical_cast<std::string>(port));
auto it = r.resolve(q);
boost::asio::ip::tcp::socket cs(ios);
boost::asio::async_connect(
cs,
it,
[&]
(boost::system::error_code const& e, boost::asio::ip::tcp::resolver::iterator) {
if (e) {
std::cout << __LINE__ << ":" << e.message() << std::endl;
return;
}
std::cout << __LINE__ << ":client connected" << std::endl;
msgpack::sbuffer sb;
msgpack::pack(sb, std::make_tuple(, false, "hello world", 12.3456));
write(cs, boost::asio::buffer(sb.data(), sb.size()));
}
);
// Start
ios.run();
}
详解:
msgpack controls a buffer
msgpack provides a buffer management functionality named msgpack::unpacker. msgpack::unpacker is sutable for the following motivations:
- msgpack data is chopped, and the client doesn't know when it will complete. This is a typical situation when you develop streaming applications.
- You want to minimize copy opperations without careful memory management.
Here is the basic (not all) interface of msgpack::unpacker:
#ifndef MSGPACK_UNPACKER_INIT_BUFFER_SIZE
#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (64*1024)
#endif #ifndef MSGPACK_UNPACKER_RESERVE_SIZE
#define MSGPACK_UNPACKER_RESERVE_SIZE (32*1024)
#endif class unpacker {
public:
unpacker(unpack_reference_func f = &unpacker::default_reference_func,
void* user_data = nullptr,
std::size_t init_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE,
unpack_limit const& limit = unpack_limit());
void reserve_buffer(std::size_t size = MSGPACK_UNPACKER_RESERVE_SIZE);
char* buffer();
void buffer_consumed(std::size_t size);
bool next(unpacked& result);
};
Here is a basic pattern using msgpack::unpacker:
// The size may decided by receive performance, transmit layer's protocol and so on.
std::size_t const try_read_size = 100; msgpack::unpacker unp; // Message receive loop
while (/* block until input becomes readable */) {
unp.reserve_buffer(try_read_size);
// unp has at least try_read_size buffer on this point. // input is a kind of I/O library object.
// read message to msgpack::unpacker's internal buffer directly.
std::size_t actual_read_size = input.readsome(unp.buffer(), try_read_size); // tell msgpack::unpacker actual consumed size.
unp.buffer_consumed(actual_read_size); msgpack::unpacked result;
// Message pack data loop
while(unp.next(result)) {
msgpack::object obj(result.get());
// Use obj
}
// All complete msgpack message is proccessed at this point,
// then continue to read addtional message.
}
msgpack::unpacker::next() returns true if one complete msgpack messege is proccessed. If msgpack message is correct but insufficient, it returns false. However, parsing proccess is proceeded and the context information is preserved in the msgpack::unpacker. It helps leveling the load of parse.
When msgpack message contains binary data, string data, or ext data, they are not copied but referenced from msgpack::object by default. See the following implementation:
inline bool unpacker::default_reference_func(type::object_type type, uint64_t len, void*)
{
return true;
}
You can also customize unpack_reference_func. Even if you use references, you don't need to control buffer's lifetime. The buffers' lifetime is controled by msgpack using msgpack::zone's finalizer_array and msgpack::unpacker's reference counting mechanism.
So, in most cases, the default behavior is enough. If you want to control the peak of memory consumption when receiving msgpack data patterns are predictable, customizing unpack_reference_func might be useful.
You can get a reference information from msgpack::unpacker::next() using the following function:
bool next(unpacked& result, bool& referenced);
However, mostly you don't need to use that version of next() because referenced memories are managed by unpacker.

MessagePack 学习笔记的更多相关文章
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
- CSS学习笔记
CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...
- HTML学习笔记
HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...
- DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记
今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...
随机推荐
- 我对android 软件栈了解
android 软件栈如图所示: Android平台的核心是Linux内核,它负责设备驱动程序.资源访问.电源管理和完成其他操作系统的职责.提供的设备驱动程序包括显示器.照相机,键盘.WiFi.闪存. ...
- Android -- View流程
在自定义view中打log,view的显示共有三种,visible.invisible和gone,分别看一下log: gone onVisibilityChanged construct 2 para ...
- Centos6.4下安装protobuf及简单使用
1.protobuf是google公司提出的数据存储格式,详细介绍可以参考:https://code.google.com/p/protobuf/ 2.下载最新的protobuf,下载地址:https ...
- JPA(三):JPA基本注解
基本注解 @Entity 标注用于实体类声明语句之前,指出该Java类为实体类,将映射到指定的数据库表.如声明一个实体类Customer,将它映射到数据的coustomer表上. package co ...
- Sublime Es6教程2-基本语法
2.基本语法 let, const, forEach,for of class, extends, super arrow functions, template string, destructur ...
- java实现文件的断点续传的下载
java的断点续传是基于之前java文件下载基础上的功能拓展 首先设置一个以线程ID为名的下载进度文件, 每一次下载的进度会保存在这个文件中,下一次下载的时候,会根据进度文件里面的内容来判断下载的进度 ...
- javascript 关键字不能作为变量来使用
var cfg={export: "export.aspx"} 这句代码中使用了一个关键字“export” 所以在IE8中报错. 那么有哪些关键字不能作为变量呢? 关键字”就是 J ...
- [Canvas]越来越近的女孩
本作比前作增加了控制功能,观看动态效果请点此下载代码用Chrome或Firfox浏览器观看. 图例: 代码: <!DOCTYPE html> <html lang="utf ...
- Spring Boot中Starter是什么
比如我们要在Spring Boot中引入Web MVC的支持时,我们通常会引入这个模块spring-boot-starter-web,而这个模块如果解压包出来会发现里面什么都没有,只定义了一些POM依 ...
- 今天发现一个神奇的网站Greasy Fork
Greasy Fork这个网站的神奇之处在于,提供了各路大神编写的脚本,可以在浏览器中实现各种神奇的功能,比如这个: 我下载使用了,确实好用,什么腾讯视频vip,爱奇艺视频vip,统统可以观看~ 并且 ...