Как решить не удалось декодировать текстовый фрейм как UTF 8, хотя увеличить веб-сокет - PullRequest
0 голосов
/ 26 июня 2019

Я пишу веб-сокет, хотя boost, и получаю сообщение, хотя клиент в chrome.Когда я использую ws, он работает хорошо, я могу получить правильное сообщение.но когда я использую wss, он работает плохо и говорит, что не может декодировать текстовый фрейм как UTF 8.

картинка - это то, что не так в режиме ssl.wrong msg in ssl mode

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)};

Откуда этот странный символ?В чем проблема?Как это исправить?

1 Ответ

1 голос
/ 26 июня 2019

Проблема с отправкой данных.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().

Быстрое решение, продлевайте время жизни строки, например, с помощью smartуказатель:

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].

...