Как я могу преобразовать сериализованные данные в boost :: beast в строку, чтобы я мог обрабатывать их в формате FIFO? - PullRequest
1 голос
/ 10 апреля 2019

У меня есть клиентское приложение, в котором мне нужно получить http "длинные запущенные запросы" с сервера. Я отправляю команду, и после получения заголовка ответа мне просто нужно получить данные json, разделенные \r\n, пока соединение не будет разорвано.

Мне удалось приспособить пример Boost Client , чтобы отправить сообщение, получить заголовок, проанализировать его и получить ответы от сервера. Однако мне не удалось найти способ сериализации данных, чтобы я мог обрабатывать сообщения json.

Ближайшая демонстрация проблемы может быть найдена в этом примере реле . В этом примере (p - синтаксический анализатор, sr - сериализатор, input - входной поток сокета и output - выходной поток сокета), после чтения заголовка http у нас есть цикл, который читает непрерывно с сервера:

do
{
    if(! p.is_done())
    {
        // Set up the body for writing into our small buffer
        p.get().body().data = buf;
        p.get().body().size = sizeof(buf);

        // Read as much as we can
        read(input, buffer, p, ec);

        // This error is returned when buffer_body uses up the buffer
        if(ec == error::need_buffer)
            ec = {};
        if(ec)
            return;

        // Set up the body for reading.
        // This is how much was parsed:
        p.get().body().size = sizeof(buf) - p.get().body().size;
        p.get().body().data = buf;
        p.get().body().more = ! p.is_done();
    }
    else
    {
        p.get().body().data = nullptr;
        p.get().body().size = 0;
    }

    // Write everything in the buffer (which might be empty)
    write(output, sr, ec);

    // This error is returned when buffer_body uses up the buffer
    if(ec == error::need_buffer)
        ec = {};
    if(ec)
        return;
}
while(! p.is_done() && ! sr.is_done());

Несколько вещей, которые я здесь не понимаю:

  1. Мы закончили читать заголовок. Почему нам нужно повысить зверя, а не повысить asio для чтения необработанного сообщения TCP? Когда я попытался сделать это (с обоими async_read / async_read_some), я получил бесконечное чтение нулевого размера.
  2. Документация parser говорит (в конце страницы), что для каждого сообщения необходим новый экземпляр, но я не вижу этого в примере.
  3. Поскольку чтение tcp-сообщения не работает, есть ли способ преобразовать данные парсера / сериализатора в какую-то строку? Даже записать его в текстовый файл в формате FIFO, чтобы я мог обработать его с помощью некоторой библиотеки json? Я не хочу использовать другой сокет, как в примере.

Функция boost::beast::buffers() не смогла скомпилировать для синтаксического анализатора и сериализатора, а для синтаксического анализатора нет функции потребления, и потребление сериализатора, по-видимому, относится к определенным http-частям сообщения, которое запускает утверждение, если я это делаю для body().

Кроме того, мне также не удалось получить согласованные порции данных из анализатора и буфера с old-school std::copy. Кажется, я не понимаю, как объединить данные, чтобы получить поток данных. Использование буфера с .consume() в любой точке при получении данных приводит к ошибке need buffer.

Буду очень признателен, если кто-нибудь объяснит логику того, как все это должно работать вместе.

1 Ответ

0 голосов
/ 11 апреля 2019

Где buf?Вы могли бы читать прямо в std::string вместо этого.Вызовите string.resize(N) и установите указатель и размер в buffer_body::value_type на string.data() и string.size().

...