javascript - How to resolve could not decode a text frame as UTF 8 though boost websocket
问题描述
I write a websocket though boost, and I receive the message though the client in chrome. When I use ws, it works well, I can receive correct msg. but when I use wss, it works bad, and said could not decode a text frame as UTF 8.
the picture is what's wrong is ssl mode.
c++ send msg code
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 code
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)};
Where does this odd character come from? What is the problem? How to fix this ?
解决方案
The problem is with sending data. async_write()
ends immediately, it doesn't make a copy of data buffer, you have to ensure that data passed into boost::asio::buffer
lives until the full message will be sent.
Even if we added some delay code between async_write
and ending brace {
:
async_write(boost::asio::buffer((void *) jsonMsg.toStyledString().data(), ..));
... some code waiting until write is completed
}
this code will not work also, because toStyledString
returns string
by value.
So temporary string
is created, string::data()
is called, async_write()
ends, and you have dangling pointer inside task initiated by async_write()
.
Quick solution, prolong lifetime of string for example by using smart pointer:
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();
}));
pass buf
by boost::asio::buffer(*buf)
, and capture it by value inside lambda: [&,sp,buf]
.
推荐阅读
- python - 没有opencv的Python Camshift算法
- javascript - addTableRow 在模板中带有一个键和一个主题
- python - 在 Python 中绘制椭球体
- javascript - 错误类型错误:无法读取未定义的属性“pageIndex”
- javascript - JavaScript 调用堆栈中的变量如何在函数返回后仍可访问
- python - 如果我将对象的名称作为字符串并且在 python 中具有属性,如何访问对象的属性?
- pandas - 使用 pd.Series.str.contains 查找列中是否存在字符串
- date - 从纪元时间转换为 (dd/mm/yyyy) 日期格式
- java - 为什么JVM突然缩小eden空间,扩大old空间?(导致性能问题)
- c++ - 是什么导致 Visual Studio 在某些机器上隐藏文件而不在其他机器上隐藏文件?