如何解决无法通过提升 websocket 将文本框架解码为 UTF 8
How to resolve could not decode a text frame as UTF 8 though boost websocket
我通过 boost 编写了一个 websocket,并且我通过 chrome 中的客户端接收了消息。
当我使用 ws 时,它运行良好,我可以收到正确的消息。
但是当我使用 wss 时,它工作不好,并说无法将文本框架解码为 UTF 8。
图片是ssl模式出了问题。
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)};
这个奇怪的字符是从哪里来的?
问题是什么?如何解决这个问题?
问题在于发送数据。 async_write()
立即结束,它不会复制数据缓冲区,您必须确保传递到 boost::asio::buffer
的数据在发送完整消息之前一直有效。
即使我们在 async_write
和结束大括号 {
之间添加了一些延迟代码:
async_write(boost::asio::buffer((void *) jsonMsg.toStyledString().data(), ..));
... some code waiting until write is completed
}
此代码也不起作用,因为 toStyledString
returns 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();
}));
通过 boost::asio::buffer(*buf)
传递 buf
,并通过 lambda 中的值捕获它:[&,sp,buf]
.
我通过 boost 编写了一个 websocket,并且我通过 chrome 中的客户端接收了消息。 当我使用 ws 时,它运行良好,我可以收到正确的消息。 但是当我使用 wss 时,它工作不好,并说无法将文本框架解码为 UTF 8。
图片是ssl模式出了问题。
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)};
这个奇怪的字符是从哪里来的? 问题是什么?如何解决这个问题?
问题在于发送数据。 async_write()
立即结束,它不会复制数据缓冲区,您必须确保传递到 boost::asio::buffer
的数据在发送完整消息之前一直有效。
即使我们在 async_write
和结束大括号 {
之间添加了一些延迟代码:
async_write(boost::asio::buffer((void *) jsonMsg.toStyledString().data(), ..));
... some code waiting until write is completed
}
此代码也不起作用,因为 toStyledString
returns 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();
}));
通过 boost::asio::buffer(*buf)
传递 buf
,并通过 lambda 中的值捕获它:[&,sp,buf]
.