2013-11-02 9 views
7

semplice scenario:Qual è il modo migliore per riconnettersi dopo il collegamento chiuso nel Netty

  1. un più basso livello di classe A che si estende SimpleChannelUpstreamHandler. Questa classe è il cavallo di battaglia per inviare il messaggio e ricevere la risposta.
  2. Una classe di primo livello B che può essere utilizzata da un'altra parte del sistema per inviare e ricevere messaggi (può simulare sia sincrono che asincrono). Questa classe crea il ClientBootstrap, imposta la factory della pipeline, invoca il bootstrap.connect() e alla fine ottiene un handle/riferimento della classe A attraverso il quale essere utilizzato per inviare e ricevere messaggi. Qualcosa di simile:

    ChannelFuture future = bootstrap.connect(); 
    Channel channel = future.awaitUninterruptibly().getChannel(); 
    

    Un gestore = channel.getPipeline(). Get (A.class);

so in classe A, posso ignorare public void channelClosed (ChannelHandlerContext CTX, ChannelStateEvent e); in modo che quando il server remoto non funziona, posso essere avvisato.

Poiché dopo la chiusura del canale, il riferimento di classe A originale (gestore precedente) nella classe B non è più valido, quindi è necessario sostituirlo con un nuovo riferimento. Idealmente, voglio che la classe A abbia un meccanismo per notificare la classe B all'interno del metodo overclided channelClosed sopra in modo che il bootstrap.connect possa essere richiamato di nuovo all'interno della classe B. Un modo per farlo è avere un riferimento in classe A quella classe di riferimento B. Per fare ciò, avrei bisogno di passare il riferimento di classe B a PipelineFactory e poi fare in modo che PipelineFactory passi il riferimento di B a A.

Qualsiasi altro modo più semplice per ottenere la stessa cosa?

grazie,

risposta

14

Channel.closeFuture() restituisce un ChannelFuture che vi informerà quando il canale è chiuso. È possibile aggiungere uno ChannelFutureListener al futuro in B in modo da poter effettuare un altro tentativo di connessione lì.

probabilmente si desidera ripetere questo fino a quando il tentativo di connessione ha esito positivo, infine:

private void doConnect() { 
    Bootstrap b = ...; 
    b.connect().addListener((ChannelFuture f) -> { 
     if (!f.isSuccess()) { 
      long nextRetryDelay = nextRetryDelay(...); 
      f.channel().eventLoop().schedule(nextRetryDelay, ...,() -> { 
       doConnect(); 
      }); // or you can give up at some point by just doing nothing. 
     } 
    }); 
} 
+1

funziona bene per me, tranne che quando uso un NioEventLoopGroup con più di 1 thread. Un nuovo thread di lavoro viene creato in ogni pianificazione (fino al massimo nel mio pool) e i thread dei vecchi worker non vengono eliminati, per quale motivo? –

Problemi correlati