Возвращает ли сервлет ответ после завершения метода 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.
Рекомендуем вам немедленно вернуться, если ничего не отвечаете, и внедрить таймер на стороне клиента (браузера), чтобы опрашивать сервер на предмет результатов очень часто.