У меня есть клиентское приложение, в котором мне нужно получить 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());
Несколько вещей, которые я здесь не понимаю:
- Мы закончили читать заголовок. Почему нам нужно повысить зверя, а не повысить asio для чтения необработанного сообщения TCP? Когда я попытался сделать это (с обоими async_read / async_read_some), я получил бесконечное чтение нулевого размера.
- Документация parser говорит (в конце страницы), что для каждого сообщения необходим новый экземпляр, но я не вижу этого в примере.
- Поскольку чтение tcp-сообщения не работает, есть ли способ преобразовать данные парсера / сериализатора в какую-то строку? Даже записать его в текстовый файл в формате FIFO, чтобы я мог обработать его с помощью некоторой библиотеки json? Я не хочу использовать другой сокет, как в примере.
Функция boost::beast::buffers()
не смогла скомпилировать для синтаксического анализатора и сериализатора, а для синтаксического анализатора нет функции потребления, и потребление сериализатора, по-видимому, относится к определенным http-частям сообщения, которое запускает утверждение, если я это делаю для body()
.
Кроме того, мне также не удалось получить согласованные порции данных из анализатора и буфера с old-school std::copy
. Кажется, я не понимаю, как объединить данные, чтобы получить поток данных. Использование буфера с .consume()
в любой точке при получении данных приводит к ошибке need buffer
.
Буду очень признателен, если кто-нибудь объяснит логику того, как все это должно работать вместе.