2013-05-10 4 views
0

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

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

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

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

Как я вижу, мне нужен способ сказать «Причал», пожалуйста, закончите текущий кусок и промойте его, но не знаете, как это сделать.

ответ

1

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

Это можно сделать с или без chunking, просто позвонив flushBuffers в ответ.

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

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

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

+0

Правда, проблема была на самом деле в Apache CXF, которая имеет ошибку в используемой нами версии, которая просто игнорирует вызовы flush(). – relgames

1

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

+0

Это не работает, сообщения по-прежнему буферизуются. – relgames

+0

см. Ответ ниже. Ваша проблема не в том, чтобы перекосить. – gregw

Смежные вопросы