自定义数据序列化 msgpack object & zone 和 wamp_message 的打包,发送

时间:2022-02-10 05:52:32

方法1 . 对于自定义数据,想通过 msgpack 打包,只需要加上 MSGPACK_DEFINE 宏 (对于版本 v1.1.x - v1.4.x), 例如

e.g 1:

struct MyPoint {
int x;
int y;
MSGPACK_DEFINE(x, y);
};

int main() {
MyPoint p1;
MyPoint p2;
msgpack::zone z; // 对于由多个成员的数据结构,msgpack 会打包成一个array,因此需要变量 zone 来组织动态分配的外部内存。一个 zone 可以保存多个object
msgpack::object o(p1, z); // p 被保存早 zone 中, zone 生存周期必须大于 object
msgpack::object o(p2, z);
return 0;
}

e.g 2(留意注释):

#include <msgpack.hpp>
#include <iostream>
#include <memory>

int main() {
{
auto z = std::make_unique<msgpack::zone>();
msgpack::object obj(std::tuple<int, bool, double>(42, true, 123.45), *z);

// oh holds one zone and four msgpack::objects
msgpack::object_handle oh(obj, std::move(z));

// convert msgpack::object to JSON
std::cout << oh.get() << std::endl;
} // one zone and four msgpack::objects are destructed here
}

方法2 . 根据自定义类型的数据添加模板函数:

see link:
1. 关于adaptor https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_adaptor
2. 使用模板的例子 https://github.com/msgpack/msgpack-c/blob/master/example/cpp03/class_non_intrusive.cpp

关于 object&zone, see wiki: https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_object
see wiki: https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_adaptor
see link: https://github.com/msgpack/msgpack-c/issues/429


在 wamp 中,所有的消息都保存在 wamp_message 这个类中,这个类有两个成员变量:msgpack::zonestd::vector<msgpack::object> :

class wamp_message
{
...
private:
msgpack::zone m_zone;
using message_fields = std::vector<msgpack::object>;
message_fields m_fields;
};

然后将 wamp_message 通过 tcp/ip 发送出去的过程:

template <class Socket>
void wamp_rawsocket_transport<Socket>::send_message(wamp_message&& message)
{
auto buffer = std::make_shared<msgpack::sbuffer>(); // std::stringstream 也可以,但是 sbuffer 更快
msgpack::packer<msgpack::sbuffer> packer(*buffer); // 创建一个 packer

// 打包所有的 msgpack::object,内容被复制到 buffer 中
packer.pack(message.fields()); // fields() 函数 return std::move( m_fields ) 即 std::vector<msgpack::object>

// Write the length prefix as the message header.
uint32_t length = htonl(buffer->size());
boost::asio::write(m_socket, boost::asio::buffer(&length, sizeof(length)));

// Write actual serialized message.
boost::asio::write(m_socket, boost::asio::buffer(buffer->data(), buffer->size()));

if (m_debug_enabled) {
std::cerr << "TX message (" << buffer->size() << " octets) ..." << std::endl;
std::cerr << "TX message: " << message << std::endl;
}
}