2014-11-07 13 views
10

Per la programmazione asincrona, Jersey (JAX-RS) fornisce una richiamata ConnectionCallback che deve essere eseguita quando una connessione è interrotta. Dal Jersey docs:AsyncResponse ConnectionCallback non attiva in Jersey

Come alcune richieste asincrone possono richiedere molto tempo per elaborare il cliente può decidere di porre fine alla sua connessione al server prima che la risposta è stato ripreso o prima che sia stato completamente scritto al cliente. A trattare con questi casi d'uso può essere usato un ConnectionCallback. Questo callback verrà eseguito solo se la connessione è stata interrotta anticipatamente oppure mentre la risposta è stata scritta sul client back . Si noti che questa richiamata non verrà invocata quando una risposta è scritta correttamente e la connessione client è chiusa come previsto.

Suona bene, ma non riesco mai a farlo sparare.

Ecco po 'di codice:

@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()); 
     } 
    }); 
} 

Gli altri due callback mostrato, CompletionCallback e TimeoutHandler, il fuoco più che bene, a colpo sicuro. Se viene raggiunta la durata di timeout specificata, TimeoutHandler si attiva. Se viene ripresa un'istanza AsyncResponse, viene attivato CompletionCallback.

Tuttavia, con ConnectionCallback, posso chiudere, uccidere o altrimenti interrompere il client seduto al servizio web mostrato sopra e ConnectionCallback non viene mai attivato.

Mi manca qualcosa? ConnectionCallback è implementato in Jersey? (È opzionale nelle specifiche JAX-RS, ma i documenti di Jersey ne parlano come se fosse implementato.)

Qualsiasi input sarebbe apprezzato.

risposta

4

ConnectionCallback è effettivamente implementato in Jersey. E 'anche invocato il callback' onDisconnect '. Si può dare un'occhiata al seguente codice nel Jersey:

https://github.com/jersey/jersey/blob/a6ff4d50da13d45ad90fd7375a15a31afa02e489/core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java#L723

https://github.com/jersey/jersey/blob/b7907e279010e7035a7a3e529993d22f77a21e08/core-server/src/main/java/org/glassfish/jersey/server/ChunkedOutput.java#L246-L252

Questi sono gettati in caso di IOException durante la scrittura di risposta. Quindi, per rispondere alla tua domanda, non esiste un meccanismo di polling o simile che continui a controllare se il client è connesso, piuttosto il metodo onDisconnect viene chiamato solo quando esiste una IOException che di solito si verifica durante la scrittura della risposta.

Update 1:

Inoltre vorrei citare alla tua domanda:

"Questa richiamata viene eseguito solo se la connessione è stata prematuramente terminato o perso mentre la risposta è di essere scritta sul retro cliente"

Quindi, a meno che non si tenta di scrivere a quella stream, il tuo callback non sarà mai attivato.Per essere chiari, non è pensato per essere chiamato quando non ci sono risposte da scrivere o quando la risposta è 202, piuttosto è pensato per essere invocato quando la connessione è stata interrotta anticipatamente mentre la risposta è stata scritta.

Ho paura che non ci sia una soluzione a questo problema se non si scrive una programmazione di rete di basso livello con il polling di qualche tipo. Ma non ti consiglierei di andare per questo.

Suggerisco di ripensare il modo in cui si desidera gestire questo errore.

+0

Ciao, grazie per la tua risposta. Avevo già stabilito che è stato implementato in Jersey anche se nel mio debugging non sono mai stato in grado di attivare un 'onDisconnect' attraverso vari mezzi per terminare la connessione client, anche se questo potrebbe essere specifico per l'ambiente. Inoltre, per quanto riguarda la taglia, ho bisogno di sapere come gestire il fatto che onDisconnect sembrerebbe accadere solo dopo aver tentato di scrivere la risposta, cioè dopo aver considerato la richiesta completa e perché non è referenziata quando non c'è un'entità scrivere (provare a catturare è solo intorno alla scrittura dell'entità, non per un 204) – James

+0

Ciao, grazie per l'aggiornamento, indipendentemente dal fatto che debba essere chiamato quando si scrive la risposta 202, che sta ancora inviando una risposta al client anche senza un corpo. Javadoc indica "Questo metodo di notifica di callback viene richiamato nel caso in cui il contenitore rilevi che la connessione client remota associata alla risposta asincrona sia stata disconnessa.". Quindi, anche se chiama su Disconnetti dopo aver completato la richiesta (che va bene suppongo) non lo farebbe se venisse scritta una risposta non-corporea. – James

+0

Penso che tu abbia ragione nel dire che avrò bisogno di un altro modo per pensarci, però ... sto davvero cercando di trovare un vincolo imposto dall'esterno che fa solo un cattivo design delle API! : S – James

Problemi correlati