Do programowania asynchronicznego, Jersey (JAX-RS) zapewnia wywołanie zwrotne ConnectionCallback
, które ma zostać wykonane, gdy połączenie zostanie zerwane. Od Jersey docs:AsyncResponse ConnectionCallback nie uruchamia się w Jersey
Ponieważ niektóre wnioski asynchroniczny może zająć dużo czasu, aby przetwarzać klient może decydują się zakończyć swoje połączenie z serwerem przed odpowiedzią zostało wznowione lub zanim został całkowicie napisany do klienta. Aby uzyskać dostęp do tych przypadków użycia, można użyć ConnectionCallback. To wywołanie zwrotne zostanie wykonane tylko wtedy, gdy połączenie zostało przedwcześnie przerwane lub utracone podczas zapisywania odpowiedzi na kliencie klienta. Zwróć uwagę, że to wywołanie zwrotne nie zostanie wywołane, gdy odpowiedź zostanie pomyślnie napisana, a połączenie z klientem zostanie zamknięte zgodnie z oczekiwaniami.
Brzmi świetnie, ale nigdy nie uda mi się tego zrobić.
Oto niektóre kodu:
@GET
@Produces(MediaType.TEXT_PLAIN)
@ManagedAsync
@Path("/poll")
public void poll(@Suspended final AsyncResponse asyncResponse) {
asyncResponse.register(new CompletionCallback() {
@Override
public void onComplete(Throwable throwable) {
logger.info("onComplete called.");
}
});
asyncResponse.register(new ConnectionCallback() {
@Override
public void onDisconnect(AsyncResponse disconnected) {
logger.info("onDisconnect called.");
}
});
asyncResponse.setTimeout(POLL_TIMEOUT_SECONDS, TimeUnit.SECONDS);
asyncResponse.setTimeoutHandler(new TimeoutHandler() {
@Override
public void handleTimeout(AsyncResponse asyncResponse) {
logger.info("handleTimeout called.");
asyncResponse.resume(Response.status(Response.Status.OK).entity("TIMEOUT").build());
}
});
}
Pozostałe dwie callbacks pokazano CompletionCallback i TimeoutHandler, ogień dobrze, bezbłędnie. Jeśli zostanie osiągnięty określony czas oczekiwania, uruchomi się TimeoutHandler. Jeśli instancja AsyncResponse zostanie wznowiona, uruchomiona zostanie funkcja CompletionCallback.
Jednak z funkcją ConnectionCallback mogę zamknąć, zabić lub w inny sposób zatrzymać klienta, który jest podłączony do usługi sieciowej pokazanej powyżej, a ConnectionCallback nigdy nie zostanie wyrzucony.
Czy brakuje mi czegoś? Czy usługa ConnectionCallback została zaimplementowana w Jersey? (Jest to opcjonalne w specyfikacji JAX-RS, ale dokumentacja firmy Jersey mówi o tym, jakby była zaimplementowana.)
Wszelkie dane wejściowe będą mile widziane.
Cześć, dziękuję za odpowiedź. Ustaliłem już, że jest on zaimplementowany w Jersey, chociaż w moim debugowaniu nigdy nie byłem w stanie wyzwolić 'onDisconnect' poprzez różne sposoby zakończenia połączenia klienta, chociaż może to być specyficzne dla środowiska. Ponadto, dla nagrody, muszę wiedzieć, jak sobie poradzić z faktem, że onDisconnect zdarzyłoby się tylko po próbie napisania odpowiedzi, tj. Po rozpatrzeniu wniosku kompletnie i dlaczego nie jest on przywoływany, gdy nie ma jednostki pisać (spróbuj złapać tylko pisanie encji, nie dla 204) – James
Cześć dzięki za aktualizację, bez względu na to, czy powinna być wywołana podczas pisania odpowiedzi 202, ponieważ wciąż wysyła odpowiedź do klienta, nawet bez ciała. Jawadok stwierdza: "Ta metoda powiadomienia zwrotnego jest wywoływana w przypadku, gdy kontener wykryje, że zdalne połączenie klienta powiązane z odpowiedzią asynchroniczną zostało odłączone.". Więc nawet jeśli zadzwoni onDisconnect po wypełnieniu żądania (co jest w porządku, jak sądzę), nie byłoby, gdyby pisano odpowiedź inną niż ciało. – James
Myślę, że masz rację mówiąc, że będę potrzebował innego sposobu, aby o tym pomyśleć ... Naprawdę staram się obejść narzucone z zewnątrz ograniczenia, które powodują zły projekt interfejsu API! : S – James