Как управлять чанками в причале?

Я пишу веб-сервис HTTP, который может занять довольно много времени, чтобы получить результаты. Я использую встроенный Jetty 8.1.5 и JAX-RS (Apache CXF)

Я решил пойти с каким-то протоколом управления: когда приходит новый запрос, я запускаю долгоиграющую работу в отдельном потоке и периодически пишу в HttpOutputStream строки с текущим статусом ("CONTROL_MESSAGE: 42% done")

Проблема в том, что Jetty использует здесь кодирование фрагментов, поэтому мои сообщения о состоянии буферизуются и бесполезны, поскольку все они могут быть буферизованы в одном фрагменте, не обеспечивая никакого прогресса для клиента.

Я не могу использовать свойство Content-Length, так как не знаю длину конечного результата. HttpOutputStream.flush() не работает, так как Jetty использует внутренние буферы.

Насколько я понимаю, мне нужен способ сказать Jetty «пожалуйста, завершите текущий фрагмент и сбросьте его», но не знаю, как это сделать.


person relgames    schedule 10.05.2013    source источник


Ответы (2)


На самом деле я не уверен, что ваша проблема заключается в фрагментации. Если я вас правильно понимаю, вы записываете прогресс в тот же поток, куда, наконец, пойдет результат?

это можно сделать с разбиением на фрагменты или без него, просто вызвав в ответе flushBuffers.

Однако это зависит от вашего подключения и вашего браузера, если это попадет в клиент. Прозрачный прокси-сервер может агрегировать содержимое и не сбрасывать его до тех пор, пока ответ не будет завершен или его собственный буфер не будет заполнен. Браузер может не обрабатывать какой-либо контент до тех пор, пока ответ не будет завершен или его буфер не будет заполнен.

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

Вам лучше использовать что-то вроде событий, отправленных сервером, веб-сокета или длительного опроса, чтобы отправить ход выполнения клиенту ..... еще лучше - просто используйте cometd.org, который выберет лучший доступный транспорт для клиента.

person gregw    schedule 17.05.2013
comment
Правда, на самом деле проблема заключалась в том, что Apache CXF имеет ошибку в используемой нами версии, заключающуюся в том, что он просто игнорирует вызовы flush(). - person relgames; 18.05.2013

Вы должны иметь возможность отключить фрагментацию, отключив само постоянное соединение, добавив заголовок Connection: close к ответу, или заранее зная Content-Length. Или я полагаю, вы могли бы просто использовать HTTP/1.0. Я открою ошибку с документацией причала, чтобы лучше задокументировать это.

person jesse mcconnell    schedule 10.05.2013
comment
см. ответ ниже. Ваша проблема не в разбиении. - person gregw; 17.05.2013