Есть ли способ отправить ответ на открытый сеанс без запроса? - PullRequest
0 голосов
/ 12 июня 2019

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

Причина в том, что происходящее событие (которое НЕ является другим запросом в том же сеансе, о котором идет речь) хочет, чтобы сервлет сказал что-то (строку) через наш старый сеанс нашему старому запрашивающему (при условии, что пришел другой запрашивающий). Есть ли способ (подсказка) сделать это?

((Изменить: Я знаю, что это не обычно для HTTP-общения. И я боюсь, что если сокет (уровня 5 OSI) закроется после завершения метода "service", тогда мой вопрос не будет решен в первую очередь, и, вероятно, мне придется остановить закрытие сокета, войдя в API серверного контейнера ("Tomcat" в моем случае). Это, вероятно, имеет место, глядя на это . ))

В любом случае, вот что я пытался сделать:

1) Я пытался сохранить объект HttpServletResponse (в методе "service") рассматриваемого сеанса, но затем, когда пришел более новый запрос (от другого запросчика) (и, как следствие, метод "service" в том же servlet, назовите его «servlet1», будет выполнен снова), мне показалось, как ни странно, ясно, что сохраненный мною HttpServletResponse перезаписан.

2) Я нашел тот же результат (я был еще более удивлен), когда я попытался сохранить объект PrintWriter (в следующем показанном коде), полученный из HttpServletResponse.getWriter (). И снова, это было перезаписано, когда пришел другой запрос.

3) У меня была надежда с HttpSession, но я сомневаюсь, что смогу написать через нее. (проверьте его методы здесь )

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

class Session {
    protected PrintWriter printWriter;
    protected int index;
    Session(PrintWriter pW, int index) {
        this.printWriter = pW;
        this.index = index;
    }
}
@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet {
private static int session_index = 0;
    protected static volatile ArrayList<Session> list = new ArrayList<Session>();

    protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
        session_index++;
        System.out.println( "Servlet1 : " + session_index );
        response.getWriter().append("Served at: ").append(request.getContextPath());
        list.add(new Session(response.getWriter(), session_index));
        if( list.get(0).printWriter.equals( response.getWriter() ) ) {
            System.out.println( "Servlet1 : same old PrintWriter object" );
        }
    }

Я ожидал, что это сообщение «Servlet1: тот же старый объект PrintWriter» не появится в моей консоли, но оно появилось во всех последующих запросах.

Это Tomcat 9.0.21, установленный в Linux, с которым я работаю на стороне сервера (localhost).

1 Ответ

0 голосов
/ 13 июня 2019

Похоже, мне нужно будет изменить сам контейнер сервера, поэтому я скачаю исходный код с здесь и буду следовать этому руководству для сборки Tomcat. Модификация должна быть сделана таким образом, чтобы не закрывать сокет. Я могу добавить метод в сервлет, чтобы закрыть сокет вручную.

...