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, который вызывает метод снова, если происходит тайм-аут, в противном случае я что-то обрабатываю на странице.

Другие вопросы по тегам