Как решить не удалось декодировать текстовый фрейм как UTF 8, хотя увеличить веб-сокет
Я пишу веб-сокет, хотя boost, и получаю сообщение, хотя клиент в chrome. Когда я использую ws, он работает хорошо, я могу получить правильное сообщение. но когда я использую wss, он работает плохо и сказал, что не может декодировать текстовый фрейм как UTF 8.
картина то, что не так, это режим ssl.
C++ отправить код MSG
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)};
Откуда этот странный персонаж? В чем проблема? Как это исправить?
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)
и захватить его по значению внутри лямбды: [&,sp,buf]
,