使用 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 形式返回的数据的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 websocket websocketpp 发送和接收消息?
未设置 set_tls_init_handler 时 websocketpp 如何处理连接?