Introduction and use of msgpack, fmtlib and RPClib Libraries

Introduction to msgpack

msgpack is an efficient binary serialization format. It's like JSON, but fast and small

Official website address: MessagePack: It's like JSON. but fast and small.

github address: GitHub - msgpack/msgpack-c at cpp_master

Like JSON, it is cross platform, cross operating system, supports multiple languages, can be used between multiple languages, and can be compressed efficiently. msgpack will package the data into binary data. Its data format is similar to json, but it has done a lot of optimization on numbers, multi byte characters, arrays and so on. It reduces the useless characters and binary format, and also ensures that there is no increase in additional storage space due to the non characterization, so it reduces the size of transmitted data to a great extent.

msgpack serialization is useful in some situations. It can replace json to realize simple and efficient message transmission. The interface can be generalized and become universal, but the readability of the message is poor.

msgpack usage

#include <vector>
#include <string>
#include <iostream>
#include <msgpack.hpp>

//Define command
#define COMMAND_GET_INFO 0x01

//Custom request class
class MyClass {
public:
    std::string m_str;
    std::vector<int> m_vec;
public:
    MSGPACK_DEFINE(m_str, m_vec);
};

int main() {
	//Parameter initialization
    MyClass my_request;
    my_request.m_str ="Hello MsgPack";
    my_request.m_vec.push_back(100);

    std::tuple<int, MyClass, std::string> send_msg(COMMAND_GET_INFO, my_request, "Addition Data");
	
	//Serialization package
    msgpack::sbuffer sbuf;
    msgpack::pack(sbuf, send_msg);

	//Network transport uses strings as messages
    std::string str(sbuf.data());

	//Deserialization unpacking
    msgpack::object_handle oh = msgpack::unpack(str.data(), str.size());
    msgpack::object deserialized_object = oh.get();
	//transformation
    std::tuple<int, MyClass, std::string> recv_msg;
    deserialized_object.convert(recv_msg);
    
	//Print
    std::cout << std::get<0>(recv_msg)<< std::endl;
    std::cout << std::get<1>(recv_msg).m_str<< std::endl;
    std::cout << std::get<2>(recv_msg)<< std::endl;
}
copy

Introduction to fmtlib

GitHub - fmtlib/fmt: A modern formatting library

fmtlib is very famous, on github 14 K stars, used by many projects.

It has also entered the standard library of C++20 (std::format), which can be regarded as the future of C + + string formatting.

In fact, the # printf # class function in the C standard library is widely used. Its main problems should be insecurity (neither type safety, but also buffer overflow), and inability to expand (incompatible with user types).

C + + streaming I/O cout and so on achieve type safety and expansibility, but it is troublesome to use In fact, the efficiency is not necessarily high.

So fmtlib was born!

fmtlib usage

It can be used to format the output:

fmt::print("Elapsed time: {0:.2f} seconds", 1.23);
fmt::print(stderr, "Don't {}!", "panic");
fmt::print("{:.2f}",0);
std::vector<int> v = {1, 2, 3};
fmt::print("{}", fmt::join(v, ", "));
copy

This format becomes very convenient. Security and efficiency are actually very high.

fmtlib mainly provides two types of API s. In addition to the fmt::print just mentioned, there is also the fmt::format function fmt::format: the task is to output the format to std::string

fmt::format basically implements most tasks of std::format However, fmt::print is not absorbed in the standard library, so the example of formatted output to in the standard is STD:: cout < < std::format (...) Such operation.

fmt::print is more efficient than "fmt::format and then output to the screen".

At present, both fmt::print and fmt::format will open a large buffer on the stack (500 characters long, which can be dynamically expanded), format and write it in, and then copy it to the screen / string Therefore, using fmt::format to output will generate std::string one step more than fmt::print Using memory on stack is much cheaper than using memory on heap, which can save some time This is actually a large SSO (short string optimization).

In addition, fmtlib also has the function of adding color to the output (through specific control characters, terminal cooperation is required), as well as safe "printf" implementation, user-defined "operator < < support and other functions. It's a bit like Python's format.

In addition, fmtlib metaprogramming is still very good. If you want to learn metaprogramming, you can basically become an expert by looking at the source code.

fmtlib is indeed perfectly in line with the performance philosophy of C + +: type safety, zero cost abstraction.

Introduction to RPClib

RPClib is a modern C++ MsPACKE RPC server and client library. It uses msgpack and the C + + format output library cppformat (now renamed fmtlib).

rpclib is the RPC Library of C + +, which provides client and server implementations. It is built using modern C++ 14, so a recent compiler is needed. Key highlights:

  • Expose program functions to be called via RPC (from any language that implements msgpack RPC)
  • Call functions via RPC (programs written in any language)
  • No IDL to learn
  • There is no code generation step in code generation, just C++

RPClib is easy to use

Server side, when SRV When run () is called, rpclib starts a server loop that listens for incoming connections and attempts to dispatch the call to the binding function. The function is called from the thread calling run. There is also an async_run generates the worker thread and returns immediately.

// Server side
#include <iostream>
#include "rpc/server.h"

void foo() {
    std::cout << "foo was called!" << std::endl;
}

int main(int argc, char *argv[]) {
    // Creating a server that listens on port 8080
    rpc::server srv(8080);

    // Binding the name "foo" to free function foo.
    // note: the signature is automatically captured
    srv.bind("foo", &foo);

    // Binding a lambda function to the name "add".
    srv.bind("add", [](int a, int b) {
        return a + b;
    });

    // Run the server loop.
    srv.run();

    return 0;
}
copy

client side:

// client side
#include <iostream>
#include "rpc/client.h"

int main() {
    // Creating a client that connects to the localhost on port 8080
    rpc::client client("127.0.0.1", 8080);

    // Calling a function with paramters and converting the result to int
    auto result = client.call("add", 2, 3).as<int>();
    std::cout << "The result is: " << result << std::endl;
    return 0;
}
copy

quote

22.5-msgpack usage - short book

C + + formatted output library fmtlib - Zhihu

Use of msgpack c + +_ Ink long day blog - CSDN blog_ c++ msgpack

Messagepack for C + + data serialization_ Blog of cancer 9 - CSDN blog_ c++ msgpack

msgpack usage_ I Tianhui I blog - CSDN blog

fmtlog: fmtlib Style C + + log library faster than NanoLog - Zhihu

Msgpack principle_ aalbertini blog - CSDN blog_ msgpack

Posted by garry on Fri, 13 May 2022 12:52:57 +0300