Próbowałem wdrożyć czat COMET, używając przetwarzania asynchronicznego zdefiniowanego w Servlet API 3. Nie działało - czat został zablokowany, więc utworzyłem serwlet debugowania, aby przetestować tylko część asynchroniczną .Tomcat 7 Awaria przetwarzania asynchronicznego - tylko jedno żądanie przetworzone jednocześnie
To jest moja metoda doGet:
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
log.debug("doGet called");
int timeout = 30 + RandomUtils.nextInt(60);
String message = RandomStringUtils.randomAlphanumeric(50 + RandomUtils.nextInt(250));
response.setHeader("Access-Control-Allow-Origin", "*");
final AsyncContext context = request.startAsync();
synchronized(items) {
items.add(new RequestItem(context, message, timeout));
}
log.debug("doGet created request and finished");
}
Kładę przedmioty zgłoszeń w kolejce, a tam bieg nici, które odbędzie się rzeczy po określonego limitu czasu i wysłać odpowiedź do AsyncContext, wiadomość druk o tym . Problem polega na tym, że wątek jest blokowany do momentu odpowiedzi AsyncContext. To jest to, co jest widoczne w moim dzienniku po zwróceniu 4 strona wczytuje w przeglądarce:
2011-12-08 13:56:36,923 DEBUG [my.servlet.TestAsyncServlet] doGet called
2011-12-08 13:56:36,952 DEBUG [my.servlet.TestAsyncServlet] doGet created request and finished
2011-12-08 13:57:39,934 TRACE [my.servlet.TestAsyncServlet] respond on item RequestItem [[email protected], message=zEQpATavzwFl6qIbBKve4OzIY9UUuZBwbqN1TC5KpU3i8LM9B6ChgUqaRmcT2yF, timeout=0]
2011-12-08 13:57:39,962 DEBUG [my.servlet.TestAsyncServlet] doGet called
2011-12-08 13:57:39,962 DEBUG [my.servlet.TestAsyncServlet] doGet created request and finished
2011-12-08 13:58:53,949 TRACE [my.servlet.TestAsyncServlet] respond on item RequestItem [[email protected], message=pKHKC632CPIk7hGLV0YqCbQl1qpWIoyNv5OWCp21bEqoni1gbY79HT61QEUS2eCjeTMoNEwdqKzCZNGgDngULysSzVdzFTnQQ5cQ8JvcYnp1pLVqGTueJPWnbRdUuO, timeout=0]
2011-12-08 13:58:53,960 DEBUG [my.servlet.TestAsyncServlet] doGet called
2011-12-08 13:58:53,960 DEBUG [my.servlet.TestAsyncServlet] doGet created request and finished
2011-12-08 13:59:36,954 TRACE [my.servlet.TestAsyncServlet] respond on item RequestItem [[email protected], message=43FPeEUZWBLqgkAqS3WOFMiHUMVvx6o4jNqWLx8kUvwxqJqpOZyGCtiIcr7yw, timeout=0]
2011-12-08 13:59:36,999 DEBUG [my.servlet.TestAsyncServlet] doGet called
2011-12-08 13:59:36,999 DEBUG [my.servlet.TestAsyncServlet] doGet created request and finished
2011-12-08 14:00:34,957 TRACE [my.servlet.TestAsyncServlet] respond on item RequestItem [[email protected], message=r69Y4NQsyR1vj0kzUlHssic2x1Yrr6T09IGKjWAH1E6Lz4VhFTy9dQHi5CPeTObyjLLBDlCLEDfiyMUnVkVIEgYG7r47Ak4w30RklhzdEi9nthqdfNkry6nyjircsFPX534NqWjI1LwsrGq5nOa3ZYtfjfPVpGlk4KDmWP11L53YntO3GmptZPKa50gcqj9i, timeout=0]
Jak to jest widzieć, kolejna metoda doGet jest wywoływana tylko po uprzednim wniosek jest (teoretycznie asynchroniczny) odpowiedział. A więc cała rzecz asynchroniczna w ogóle nie działa! A oto deklaracja web.xml:
<servlet>
<servlet-name>TestAsyncServlet</servlet-name>
<servlet-class>my.servlet.TestAsyncServlet</servlet-class>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>TestAsyncServlet</servlet-name>
<url-pattern>/test-async</url-pattern>
</servlet-mapping>
Robię wszystko, co można znaleźć w Internecie. Nie widzę miejsca popełnienia błędu. Nie znalazłem nic specjalnego do skonfigurowania w servlet.xml. Pytanie brzmi: dlaczego nie działa tak, jak powinno?
O dziwo, Chrome i Firefox wydają się serializować wiele żądań GET, jeśli adres URL jest taki sam. Safari tego nie robi. – Mark