我通过boost编写了一个websocket,并且通过chrome客户端收到了消息。 当我使用ws时,它运作良好,我可以收到正确的味精。 但是当我使用wss时,它工作不正常,并说不能将文本帧解码为UTF 8。
c ++发送味精代码
Json::Value jsonMsg;
jsonMsg["msgType"] = Json::Value("MspServiceStartUp");
jsonMsg["version"] = Json::Value(std::string(MSP_VERSION));
ws_->async_write(boost::asio::buffer((void *) jsonMsg.toStyledString().data(), jsonMsg.toStyledString().size()),
boost::asio::bind_executor(*strand_, [&, sp](boost::system::error_code ec1,
std::size_t bytes_transferred1) {
boost::ignore_unused(bytes_transferred1);
if (ec1) {
LOG_ERR << "async write failed, ec = " << ec1 << ", msg = "
<< ec1.message();
return;
}
// Clear the buffer
buffer_->consume(buffer_->size());
task();
}));
}
js代码
var ws=new WebSocket("wss://localhost.com:17801/");
ws.onopen=()=>{console.log('ws open')};
ws.onclose=()=>{console.log('ws close')};
ws.onmessage=(msg)=>{console.log('ws onMessage');console.log(msg)};
这个奇怪的字符从哪里来? 问题是什么?该如何解决?
答案 0 :(得分:1)
问题在于发送数据。 async_write()
立即结束,它不会复制数据缓冲区,您必须确保传递到boost::asio::buffer
的数据有效,直到发送完整的消息为止。
即使我们在async_write
和括号{
之间添加了一些延迟代码:
async_write(boost::asio::buffer((void *) jsonMsg.toStyledString().data(), ..));
... some code waiting until write is completed
}
该代码也将不起作用,因为toStyledString
返回string
按值。
这样就创建了临时string
,调用了string::data()
,结束了async_write()
,并且您在async_write()
启动的任务中悬挂了指针。
快速解决方案,例如通过使用智能指针来延长字符串的寿命:
std::shared_ptr<std::string> buf(std::make_shared<std::string>(jsonMsg.toStyledString()));
ws_->async_write(boost::asio::buffer(*buf),
boost::asio::bind_executor(*strand_,
[&, sp, buf](boost::system::error_code ec1,
std::size_t bytes_transferred1)
{
boost::ignore_unused(bytes_transferred1);
if (ec1) {
LOG_ERR << "async write failed, ec = " << ec1 << ", msg = "
<< ec1.message();
return;
}
// Clear the buffer
buffer_->consume(buffer_->size());
task();
}));
通过buf
传递boost::asio::buffer(*buf)
,并通过lambda中的值捕获它:[&,sp,buf]
。