2016-05-10 4 views
0

My I/O Fluss folgt:Netty - Feuer ReadTimeoutHandler wenn mehrere liest in Kanal

  1. Client sendet 1 Daten #
  2. Server (handler) empfängt von Datenbankdaten zum Kanal, um die Client-Daten nach und sendet es an den Client
  3. Client sendet Daten # 2
  4. Server (handler) empfängt Daten wieder auf Kanal von der Datenbank die Clientdaten nach und sendet sie zurück an den Client und beendet Kanal

Wenn der erste eingelesene Kanal zu lange dauert, löst ReadTimeoutHandler die Ausnahme wie erwartet aus. Aber wenn das erste Lesen ok ist (= schnell genug) und das zweite Einlesen der Kanäle zu lange dauert, wird keine TimeoutException ausgelöst und der Handler wartet 5 Minuten, bis er den Kanal schließt. Es scheint, dass ReadTimeoutHandler nur für den ersten eingelesenen Kanal funktioniert. Ist es überhaupt möglich ReadTimeoutHandler mit mehreren Reads im Channel zu arbeiten?

Gebrauchte Netty Version: 4.0.12

public class MyServer {

private static final class MyInitializer extends ChannelInitializer<SocketChannel> { 

... 

    @Override 
    public void initChannel(SocketChannel channel) throws Exception { 
     channel.pipeline().addLast(
       new ReadTimeoutHandler(5, TimeUnit.SECONDS), 
       new MyHandler(server, serverConnection)); 
    } 

... 

} 

}

public class MyHandler erweitert SimpleChannelInboundHandler {

private static final Logger LOG = LoggerFactory.getLogger(MyHandler.class); 

@Override 
public void channelActive(ChannelHandlerContext ctx) throws Exception { 
    super.channelActive(ctx); 
} 

@Override 
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { 
    Message message = database.getMessage(msg); 
    ChannelFuture operation = ctx.writeAndFlush(message) 

if (message.isEnd()) operation.addListener(new CloseConverstationListener(ctx)); 
} 

@Override 
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 
    if (cause instanceof ReadTimeoutException) { 
     LOG.error("ReadTimeoutException"); 
    } 
} 

@Override 
public void channelInactive(ChannelHandlerContext ctx) throws Exception { 
    super.channelInactive(ctx); 
} 

private class CloseConverstationListener implements GenericFutureListener<ChannelFuture> { 
    private final ChannelHandlerContext ctx; 

    private CloseConverstationListener(ChannelHandlerContext ctx) { 
     this.ctx = ctx; 
    } 

    @Override 
    public void operationComplete(ChannelFuture future) throws Exception { 
     future.channel().close().sync(); 
    } 
} 

}

+0

Sind Sie sicher, dass Sie Ihre vollständige Pipeline veröffentlicht haben? Es gibt keine Konversation von Bytes zu Strings. – Ferrybig

Antwort

0

Das ReadTimeoutHandler-Verhalten ist - Wenn in einem Kanal für die angegebene Dauer keine Lesevorgänge stattfinden, wird eine Ausnahme ausgelöst und der Kanal geschlossen. Es ist nicht für die Verzögerung beim Reagieren oder Verarbeiten eines Lesevorgangs. Zu Beginn des Lesens des Kanals wird das Lese-Flag auf "Wahr" gesetzt, und es wird auf "Falsch" gesetzt, wenn der Lesevorgang beendet ist. Es wird ein Scheduler ausgeführt, der prüft, ob der Kanal offen ist und für die angegebene Dauer nicht gelesen wurde, dann löst er die Ausnahme aus und schließt die Verbindung.

Wenn der erste eingelesene Kanal zu lange dauert, löst ReadTimeoutHandler die Ausnahme wie erwartet aus.

Das oben genannte klingt für mich nicht korrekt. Wenn Sie Timeout basierend auf Verzögerung beim Schreiben einer Antwort möchten, könnten Sie WriteTimeoutHandler in Betracht ziehen.

+0

Danke für die Antwort. Trotzdem denke ich, ReadTimeoutHandler funktioniert in meinem Fall nicht richtig oder ich verstehe nicht, wie es funktionieren soll. Es funktioniert für das erste Lesen in dem Kanal für den Fall, dass es abläuft, aber wenn der zweite (oder dritte usw.) gelesen wird, löst ReadTimeoutHandler keine Ausnahme aus, z. wenn der Client die Verbindung trennt und kein weiterer Lesevorgang stattfindet. ReadTimeoutHandler channelRead-Methode wird aufgerufen (wieder), aber es wird nie eine Ausnahme auslösen, weil ReadTimeoutHandler Zustand ist nach dem ersten Lesen 1 (oder 2?), Und ich richtig verstanden, sollte Wert 0 sein, dass Scheduler-Task erneut ausgelöst wird. – vrds

+0

Wenn der Client die Verbindung trennt, sind keine aktiven Kanäle vorhanden. Wenn es einen aktiven Kanal gibt und für die angegebene Dauer kein Lesezugriff auf den Kanal erfolgt, löst dieser Handler Exception aus und schließt den Kanal. Dies dient dazu, unerwünschtes Kanalwachstum zu verhindern. HTH –

Verwandte Themen