Возвращает ли сервлет ответ после завершения метода doGet?

Очевидно, что doGet Метод имеет тип возврата void, поэтому он ничего не возвращает. В этом смысле я использую слово "возврат", чтобы означать отправку ответа клиенту, который его запросил.

Я пытаюсь реализовать сервлет с длинным опросом. Было бы полезно, чтобы он не отправлял ответ, пока у меня не будет чего-то, что я хотел бы отправить обратно. Итак, в методе doGet я добавляю идентификатор подключенного пользователя и AsyncContext на карту:

private ConcurrentMap<String, AsyncContext> contexts = new ConcurrentHashMap<>();
//...in the doGet method when I need to add the context...
contexts.put(userId, context);

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

AsyncContext context = contexts.get(userId);
PrintWriter writer = context.getResponse().getWriter();
writer.write("something to send to the client");

Но клиент никогда не получает ответ. Глядя на вкладку Сеть в консоли разработчика браузера, я вижу, что запрос GET отправляется, а затем возвращается (со статусом 200). Это происходит до того, как я что-то отправлю обратно. Что приводит меня к мысли, что после завершения метода doGet ответ возвращается. И, возможно, из-за этого после этой точки клиенту ничего нельзя отправить, потому что соединение не открыто.

Посылает ли метод doGet ответ клиенту после завершения выполнения метода? Если это так, как я могу сохранить соединение открытым для эффекта длительного опроса?

2 ответа

Решение

Чтобы ответить на мои собственные вопросы: Does the doGet method send the response to the client once the method is finished executing?

Да, когда метод doGet (или любой метод HttpServlet, например: doGet, doPost и т. Д.) Завершает выполнение, он отправляет ответ клиенту.

If this is the case, how can I keep the connection open for a long-polling effect?

Используя асинхронные сервлеты (которые я использовал, однако я обнаружил, что моя конкретная проблема должна быть в другом месте, но эти ответы по-прежнему актуальны для задаваемых вопросов). Для объекта ServletRequest вызовите метод startAsync, например, так:

AsyncContext context = request.startAsync(request, response);

"Это уведомит веб-контейнер о том, что в конце вызова запроса он должен освободить поток обработки и оставить соединение открытым, чтобы другой поток записал ответ и завершил соединение". Ссылка Ссылка.

Кроме того, я добавлю решение моей конкретной проблемы (клиент не получил ответ) потому, что в моем сервлете я не вызывал полный метод объекта AsyncContext:

asyncContext.complete();

Да, поток ответов сбрасывается и закрывается, когда doGet() завершает выполнение.

Занятость потоков пользовательского интерфейса в течение длительных периодов времени нарушает передовой опыт Java Enterprise.

Рекомендуем вам немедленно вернуться, если ничего не отвечаете, и внедрить таймер на стороне клиента (браузера), чтобы опрашивать сервер на предмет результатов очень часто.

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