使用 websocketpp 以 json 形式返回的数据,但使用 messagepack 以 Blob 形式返回的数据

Posted

技术标签:

【中文标题】使用 websocketpp 以 json 形式返回的数据,但使用 messagepack 以 Blob 形式返回的数据【英文标题】:Data returned as json with websocketpp but as Blob with messagepack 【发布时间】:2015-10-31 11:15:09 【问题描述】:

这很奇怪。我已经使用用 C++ 编写的 websocketpp 修改了一个 websocket-server 示例。它使用 nlohmann/json 解析来自客户端的传入字符串化 json 数据。数据以 json 格式返回给客户端,解析并更新一个 hmtl div。到目前为止一切都很好。

然后我想使用 messagepack 压缩来自客户端的 json 数据,解析并以相同的 json 格式返回它,但现在我收到一个错误,因为数据现在是 [object Blob]。我安装了wireshark,但它们在两种情况下捕获的信息完全相同。

两者都返回为

$"cnt":4,"data":"test","type":"msg"

长度为 38。

在 chrome 中我得到错误

Uncaught SyntaxError: Unexpected token o

这是添加消息包之前的客户端:

function sendMessage () 
    var m = document.getElementById("messageField").value;
    var msg = 
        "type": "msg",
        "data": m
    
    msg = JSON.stringify(msg);
    ws.send(msg);

以及添加消息包之前的C++服务器:

void on_message(connection_hdl hdl, server::message_ptr msg) 
    connection_ptr con = m_server.get_con_from_hdl(hdl);

    std::string payload = msg->get_payload();
    try 
        auto jdata = nlohmann::json::parse(payload);

        if (jdata["type"] == "lgn") 
            std::string lname = jdata["data"];
            if (con->name == "") 
                con->name = lname;
            
        

        if (jdata["type"] == "msg") 
            std::string clientmsg = jdata["data"];
            jdata["cnt"] = clientmsg.length();
            msg->set_payload(jdata.dump());
            m_server.send(hdl, msg);
        
     catch (const std::exception& e) 
        msg->set_payload("Unable to parse json");
        m_server.send(hdl, msg);
        std::cerr << "Unable to parse json: " << e.what() << std::endl;
    

非常基本。下面是添加消息包后的客户端和服务器:

function sendMessage () 
    var m = document.getElementById("messageField").value;
    var msg = 
        "type": "msg",
        "data": m
    
    msg = JSON.stringify(msg);
    var buffer = msgpack.encode(msg);
    ws.send(buffer);

只添加

var buffer = msgpack.encode(msg);

并相应地更改 ws.send()。

void on_message(connection_hdl hdl, server::message_ptr msg) 
    connection_ptr con = m_server.get_con_from_hdl(hdl);

    std::string payload = msg->get_payload();

    // Parse messagepack
    msgpack::unpacked unpacked_msg;
    msgpack::unpack(&unpacked_msg, payload.data(), payload.size());
    msgpack::object obj = unpacked_msg.get();
    std::string sobj;
    obj.convert(&sobj);

    try 
        auto jdata = nlohmann::json::parse(sobj);

        if (jdata["type"] == "lgn") 
            std::string lname = jdata["data"];
            if (con->name == "") 
                con->name = lname;
            
        

        if (jdata["type"] == "msg") 
            std::string clientmsg = jdata["data"];
            jdata["cnt"] = clientmsg.length();
            msg->set_payload(jdata.dump());
            m_server.send(hdl, msg);
        
     catch (const std::exception& e) 
        msg->set_payload("Unable to parse json");
        m_server.send(hdl, msg);
        std::cerr << "Unable to parse json: " << e.what() << std::endl;
    

添加

    // Parse messagepack
    msgpack::unpacked unpacked_msg;
    msgpack::unpack(&unpacked_msg, payload.data(), payload.size());
    msgpack::object obj = unpacked_msg.get();
    std::string sobj;
    obj.convert(&sobj);

并相应地更改 nlohmann::json::parse()。

奇怪的是我只使用messagepack atm。压缩传入的 json 数据但不压缩。如果这个问题得到解决,我将同时使用它。一定有一些我忽略的东西,感谢您的帮助。

【问题讨论】:

我添加了一个新的 FileReader() 并读取了包含 json-data 的结果。 【参考方案1】:

也许为时已晚,但 nlohmann/json 现在也支持 MessagePack,因此您可能不需要为 MessagePack 编码使用特殊库。有关示例,请参阅https://github.com/nlohmann/json#binary-formats-cbor-and-messagepack。

【讨论】:

这是一个边界线link-only answer。您应该在此处扩展您的答案以包含尽可能多的信息,并仅将链接用作参考。【参考方案2】:

我在客户端的 WebSocket.onmessage() 中添加了一个 FileReader() 来提取 json-data。

document.addEventListener("DOMContentLoaded", function () 
    if (window.WebSocket) 
        // Let us open a web socket.
        var hname = window.location.hostname;
        ws = new WebSocket("ws://" + hname + ":9002");
        ws.onmessage = function (e) 
            var reader = new FileReader();
            reader.onload = function (e) 
                console.log(reader.result);
                var receivedMsg = JSON.parse(reader.result);
                alert("Message received: " + receivedMsg.data);
                document.getElementById("parsedFromServer").innerhtml = "Text sent: " + receivedMsg.data + ", length: " + receivedMsg.cnt;
            

            reader.readAsText(e.data);
        
     else 
        alert("Websocket unsupported");
    
);

【讨论】:

以上是关于使用 websocketpp 以 json 形式返回的数据,但使用 messagepack 以 Blob 形式返回的数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 websocketpp 中使用自定义记录器?

如何使用 websocket websocketpp 发送和接收消息?

未设置 set_tls_init_handler 时 websocketpp 如何处理连接?

使用 websocketpp 时“调用绑定没有匹配的函数”

在 Windows 上使用 websocketpp 和 MySQL 提升构建错误

Windows下使用websocketpp