Асинхронная функция Servlet 3.0 и push на стороне сервера

Я ищу какой-нибудь API, который фактически отправляет данные клиенту. Прямо сейчас я использую атмосферу с длинным опросом для достижения этой цели. Я использую Glassfish 3.1.2 с кометой.

Позже я услышал об асинхронной функции Servlet 3.0. Затем я попытался понять, могу ли я использовать его для замены атмосферы или нет.

Идея состоит в том, чтобы иметь сервлет, который при получении запросов будет помещать их в список, который находится в области приложения. Затем, через некоторое неопределенное время, я получаю еще один запрос, который затем повторяет список и отправляет ответ клиентам.

Я написал первый сервлет, который получает запросы и помещает AsyncContext в список области действия приложения. Затем я проверил, создается ли AsyncContext или нет. Я написал вызов ajax, который фактически попадает в URL-адрес. Время ожидания запроса ajax истекло/умерло через 30 секунд. Затем позже я попытался установить тайм-аут AsyncContext и установил для него отрицательное значение, чтобы тайм-аут никогда не происходил. Позже я понял, что setTimeOut(int) в AsyncContext предназначен для другой цели. Теперь я не могу установить время как что-то очень большое, так как я не знаю, сколько часов или дней потребуется, чтобы отправить ответ.

Тогда я подумал установить тайм-аут запроса на какой-то неопределенный. Но я не знаю, как это сделать.

То же самое можно сделать в атмосфере, используя resource.suspend(), который приостанавливает запрос на неопределенное время.

Если я не могу использовать для этого асинхронную функцию Servlet 3.0, то в чем ее цель?

Что я понял об этой функции, так это то, что если запрос ожидает какого-либо ресурса, скажем, соединения jdbc, тогда запрос помещается в очередь, а поток возвращается обратно в пул потоков, чтобы поток был доступен для обслуживания других запросов. . Эта ссылка фактически запускает асинхронный процесс, передает объект в Runnable и выходит из метода doGet. . Если в случае, если Runnable требуется время для обслуживания запроса из-за ожидания какого-либо ресурса, то поток помещается обратно в пул потоков и перерабатывается. Правильно ли я понимаю? Если я правильно понимаю, то, если запрос превышает максимальное время ожидания ресурса, время ожидания истечет, и клиенту будет отправлено какое-то исключение. Как установить тайм-аут на неопределенный программно и добиться толчка на стороне сервера без атмосферы.

Во многих документах говорится, что асинхронные сервлеты могут использоваться для передачи данных клиентам. Если все клиенты используют длительный опрос, и если асинхронность не поддерживается сервером, для каждого запроса должен быть выделен один поток, который истощает все потоки и использует много памяти. Если асинхронность поддерживается, все запросы будут поставлены в очередь, а потоки будут свободны для обслуживания других запросов. Ссылка здесь объясняет то же самое. Но я не вижу никакого способа приостановить запрос, пока мы не получим событие, а не тайм-аут. Как фреймворкам вроде атмосферы удается приостановить запрос? Я думаю, что если HTTP-запрос можно приостановить в сервлете 3.0, то нам не нужны никакие рамки, такие как атмосфера. Даже длинный опрос должен подойти вместо веб-сокетов, потому что потоки не всегда будут присоединяться к запросу в соответствии с асинхронной функцией сервлета 3.0.


person Krishna Chaitanya    schedule 02.09.2013    source источник


Ответы (1)


Я получил ответ. После небольшой отладки метода suspend() в атмосфере я узнал, что метод suspend() не будет приостанавливать HTTP-запрос на неопределенное время. Он приостанавливает HTTP-запрос до истечения времени ожидания сеанса, потому что нет смысла в том, что сеанс истек, а запрос все еще находится в очереди.

Теперь я хочу заменить структуру атмосферы и использовать асинхронную функцию сервлета 3.0.

Клиент отправит запрос. В моем сервлете я инициирую asyncStart (req, res), а затем устанавливаю тайм-аут на тайм-аут сеанса. Между тем, если произойдет событие, в Runnable я зафиксирую ответ. Затем клиент сделает еще один запрос.

Вот мой пример кода

AsyncContext actxt = request.startAsync(request, response);
actxt.setTimeout(request.getMaxInactiveInterval());
executor.execute(new MyService(actxt));

Затем я создам свою собственную шину событий, используя шаблон Observer. Класс MyService реализует обработчик событий. Через некоторое время событие будет запущено, и все экземпляры MySevice получат это событие и зафиксируют ответ.

Пожалуйста, дайте мне знать, правильный мой подход или нет, или можно ли улучшить этот подход.

person Krishna Chaitanya    schedule 03.09.2013