Клиент (javascript) не может получить изображение или двоичный файл с сервера, используя boost beast и opencv - PullRequest
0 голосов
/ 10 июня 2019

Я использовал один из примеров асинхронного веб-сервера boost :: beast для связи с клиентским JavaScript с помощью websocket. Я пытаюсь сделать простое получение изображения и записать его на стороне сервера.

Результат, который я получаю на стороне сервера, - это изображение в формате jpg. Заранее спасибо.

на стороне клиента (javascript)

var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var img = document.getElementById("image");

var ws = null;
connect.onclick = function() {
   ws = new WebSocket(uri.value);
   ws.onopen = function(ev) {
     messages.innerText += "[connection opened]\n";
   };
   ws.onclose = function(ev) {
     messages.innerText += "[connection closed]\n";
   };
   ws.onmessage = function(ev) {
     messages.innerText += ev.data + "\n";
   };
   ws.onerror = function(ev) {
     messages.innerText += "[error]\n";
     console.log(ev);
   };
 };
disconnect.onclick = function() {
   ws.close();
};
send.onclick = function() {
   var canvas1 = ctx.getImageData(0,0,img.width,img.height);
   var binary = new Uint8Array(img.data.length);
   for (var i=0; i<img.data.length; ++i) {
     binary[i] = img.data[i];
   }

   ws.send(binary.buffer);
}

на стороне сервера

void on_write(boost::system::error_code ec,
        std::size_t bytes_transferred)
{
   boost::ignore_unused(bytes_transferred);

   if(ec)
     return fail(ec, "write");

   buffer_.consume(buffer_.size());

   std::cout << "on write before do read\n";

   ws_.async_read(
            buffer_,
            boost::asio::bind_executor(
                strand_,
                std::bind(
                    &session::on_read,
                    shared_from_this(),
                    std::placeholders::_1,
                    std::placeholders::_2)));
   uint8_t *buf = new uint8_t [bytes_transferred];


boost::asio::buffer_copy(boost::asio::buffer(buf,bytes_transferred),buffer_.data(),bytes_transferred);
        ::cv::Mat mImg(400,320,CV_8UC3,buf);
        ::cv::imwrite("file.jpg",mImg);
      delete [] buf;

    }

1 Ответ

0 голосов
/ 10 июня 2019

Сначала я рекомендую рефакторинг вашего кода в небольшие тестируемые функции.

Напишите такую ​​функцию:

template <class AsyncStream, class CompletionToken>
auto
async_write_opencv_image(AsyncStream&, CompletionToken&& token)
{
  // write composed op here
}

Используя это, вы можете ввести boost::beast::test::stream в функцию, которая позволит вам вручную проверять буферы, чтобы гарантировать правильность изображения.

Это имеет то преимущество, что теперь ваш код записи изображений не зависит от потока, поэтому вы можете поменять его на любой другой тип.

Если вам нужна какая-либо помощь в этом отношении, на boost.org имеется достаточно документации, а также оперативная помощь команде cpplang slack.

Edit:

Вот пример wandbox, как также потенциально настроить юнит-тест для веб-сокетов: https://wandbox.org/permlink/EixDmotCphJwiDZ1

...