【问题标题】:I would like to parse a boost::beast::flat_buffer with msgpack data using nlohmann:json我想使用 nlohmann:json 解析带有 msgpack 数据的 boost::beast::flat_buffer
【发布时间】:2021-10-21 05:38:15
【问题描述】:

所以我使用 boost::beast 作为 WebSocket 服务器。 我想接收一个二进制消息并使用 nlohmann::json 解析它。 但是我收到一条错误消息:

3 个重载都不能转换参数“nlohmann::detail::input_adapter”

这里有一些代码:

        boost::beast::flat_buffer buffer;
        ws.read(buffer);
        if (!ws.got_text()) {
            ws.text(false);
            json request = json::from_msgpack(msgpack);
            ws.write( json::to_msgpack(request) ); // echo request back
        }

如果我尝试将静态转换为 std::vector 我得到: E0312 / 没有合适的用户自定义转换

        boost::beast::flat_buffer buffer;
        ws.read(buffer);
        if (!ws.got_text()) {
            ws.text(false);
            boost::asio::mutable_buffer req = buffer.data();
            //unsigned char* req2 = static_cast<unsigned char*>(req);                     // does not work
            //std::vector<std::uint8_t> req2 = static_cast<std::vector<std::uint8_t>>(req); // does not work
            json request = json::from_msgpack(buffer.data());
            ws.write(boost::asio::buffer(json::to_msgpack(request)));
        }

如何从缓冲区中取出二进制数据以便 nkohman::json 解析它?

【问题讨论】:

  • 你试过json::parse((char*)req.data(), (chjar*)req.data+req.size()) 吗?
  • 感谢您的想法,但这给出了 E0413 没有转换功能

标签: c++ boost boost-asio msgpack nlohmann-json


【解决方案1】:

您可以使用基于迭代器的重载:

Live On Compiler Explorer

#include <boost/asio/buffers_iterator.hpp>
#include <boost/beast.hpp>
#include <boost/beast/websocket.hpp>
#include <nlohmann/json.hpp>

int main() {
    using nlohmann::json;
    using boost::asio::ip::tcp;
    boost::asio::io_context io;
    boost::beast::websocket::stream<tcp::socket> ws(io);

    boost::beast::flat_buffer buffer;
    ws.read(buffer);
    if (!ws.got_text()) {
        ws.text(false);

        auto req     = buffer.data();
        auto request = json::from_msgpack(buffers_begin(req), buffers_end(req));

        ws.write(boost::asio::buffer(json::to_msgpack(request)));
    }
}

ADL 会找到合适的重载(boost::asio::buffers_begin 例如在这种情况下)

【讨论】:

  • 它编译,你是我的英雄!我现在正在测试细节!