JAX-RS и длинный опрос
Я пытаюсь использовать длинный опрос с JAX-RS (реализация на Джерси), и он не работает так, как я ожидаю. Может быть, я что-то неправильно понимаю. Буду признателен за любые советы.
Обратите внимание, что использование обратного соединения (например, Atmosphere, Comet и т. Д.) Не является вариантом по соображениям безопасности. Не то чтобы я сейчас занимаюсь разработкой с Tomcat 7.
Следующий метод вызывается из вызова JQuery Ajax (используя $.ajax
).
@Path("/poll")
@GET
public void poll(@Suspended final AsyncResponse asyncResponse)
throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
this.asyncResponse = asyncResponse;
// wait max. 30 seconds using a CountDownLatch
latch.await(getTimeout(), TimeUnit.SECONDS);
}
}).start();
}
Другой метод вызывается из моего приложения (после вызова JMS):
@POST
@Path("/printed")
public Response printCallback() {
// ...
// I expect the /poll call to be ended here from the client perspective but that is not the case
asyncResponse.resume("UPDATE");
latch.countDown();
return Response.ok().build();
}
Если я удалю создание темы в poll
метод. Тогда это работает, но проблема в том, что поток занят. Если я использую создание потока, то метод возвращается напрямую, и браузер не определяет конец длинного опроса.
Что я делаю неправильно?
1 ответ
Я нашел решение своей проблемы. Проблема была в конфигурации. Мы должны указать, что сервлет Джерси поддерживает async
а то работает нормально
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<async-supported>true</async-supported>
...
</servlet>
Обратите внимание, что если у вас есть фильтры сервлетов, они также должны быть async-supported
в true.
Это также не было необходимо для создания потока. Джерси делает это для меня:
@Path("/poll")
@GET
public void poll(@Suspended final AsyncResponse asyncResponse)
throws InterruptedException {
asyncResponse.setTimeout(30, TimeUnit.SECONDS);
this.asyncResponse = asyncResponse;
}
@POST
@Path("/printed")
public Response printCallback(String barcode) throws IOException {
// ...
this.asyncResponse.resume("MESSAGE");
return Response.ok().build();
}
При звонке poll
браузер ждет до получения MESSAGE
или получение статуса HTTP 503, если истекло время ожидания. На сервере поток запросов не блокируется до истечения времени ожидания, а освобождается напрямую. На стороне клиента у меня есть JavaScript, который вызывает метод снова, если происходит тайм-аут, в противном случае я что-то обрабатываю на странице.