24 Mayıs 2018 Perşembe

Netty ChannelInboundHandlers

Giriş
ChannelInboundHandler'dan kalıtan sınıflarda state saklanabilir.

ChannelHandlerAdapter Sınıfı
Şu satırı dahil ederiz.
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
channelInactive metodu
İmzası şöyle.
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception;
channelRead metodu
İmzası şöyle.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception;
channelRegistered metodu
İmzası şöyle.
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception;
channelUnregsitered metodu
İmzası şöyle.
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception;
Açıklaması şöyle.
When you deregister a Channel it basically removed itself from the servicing Thread which in the case of NIO also is the Selector itself. This means you will not get notified on any event changes. Once you register again the Channel will be registered on a Selector again and you will get noticed about events (like OP_READ, OP_WRITE etc).
write metodu
İmzası şöyle.
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
 throws Exception
ChannelInboundHandlerAdapter Sınıfı - Eski
Netty 5 ile bu sınıf kalktı. ChannelHandlerAdapter kullanılmalı.

Giriş
Şu satırı dahil ederiz
import io.netty.channel.ChannelInboundHandlerAdapter;
Şöyle yaparız. Bu sınıftan kalıtmak yerine SimpleChannelInboundHandler sınıfından kalıtmak daha iyi gibi görünüyor.
public class TimeServerHandler extends ChannelInboundHandlerAdapter {
  ...
}
channelActive metodu
Netty 4 ile geliyor. Eski kodlar için açıklaması şöyle.
channelOpen, channelBound, and channelConnected have been merged to channelActive. 
Channel connected anlamına gelir. Şöyle yaparız.
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
  channels.add(ctx.channel());
  // ...
}
channelInactive metodu
Netty 4 ile geliyor. Açıklaması şöyle.
will only be called when the channel is closed. This is the contract.
Eski kodlar için açıklaması şöyle.
channelDisconnected, channelUnbound, and channelClosed have been merged to channelInactive
Channel kapatıldı anlamına gelir. Şöyle yaparız.
@Override
public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
  channels.remove(ctx.channel());
}
channelRead metodu
Okumaya hazır anlamına gelir.

Örnek
msg parametresi istediğimiz nesne tipine cast edilebiliyorsa şöyle yaparız.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  RpcResponse response = (RpcResponse) msg;
  ...  
}
Örnek
Şöyle yaparız. msg prametresini ByteBuf nesnesine cast etmek gerekiyoesa ByteBuf relase() edilmelidir.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
  ByteBuf ioBuffer = (ByteBuf) msg;
  ...
}
Örnek
Şöyle yaparız.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  // ...

  for (Channel ch : channels1) {
    // Does `ch` represent the channel of the current sending client?
    if (ch.equals(ctx.channel())) {
      // Skip.
       continue;
    }

    // Send the message to the `ch` channel.
    // ...
  }

  // ...
}
Örnek
Şöyle yaparız. msg prametresini ByteBuf nesnesine cast etmek gerekiyoesa ByteBuf relase() edilmelidir.
@Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg)
throws Exception {
  final ByteBuf buff = (ByteBuf) msg;
  try {
    if (clientSocketChannel != null){
      clientSocketChannel.writeAndFlush(buff.retain()).sync();    
    }
  } finally {
    buff.release();
  }
}
channelReadComplete metodu
Okuma işlemi bitti anlamına gelir. Şöyle yaparız.
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
  super.channelReadComplete(ctx);
}
exceptionCaught metodu
Örnek
Şöyle yaparız.
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  super.exceptionCaught(ctx, cause);
}
Örnek
Şöyle yaparız.
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  logger.error("Error in netty read/write: ", cause);
}
handlerAdded metodu
Açıklaması şöyle.
A ChannelHandler has two life cycle listener methods: handlerAdded() and handlerRemoved(). You can perform an arbitrary (de)initialization task as long as it does not block for a long time.
Örnek ver

handlerRemoved metodu
Örnek ver

ChannelInboundMessageHandlerAdapter Sınıfı - Eski
Netty 5 ile bu sınıf kalktı. SimpleChannelInboundHandler kullanılmalı.

IdleStateHandler Sınıfı
Giriş
Hem ChannelInboundHandler hem de ChannelOutboundHandler arayüzünden kalıtır.

constructor
Örnek
Read işlemi beliritilen süre kadar olmazsa event fırlatmak için şöyle yaparız.
.addLast(new IdleStateHandler(appIdleTimeout, 0, 0))
.addLast(myChannelInboundHandlerAdapter)
Örnek
Şöyle yaparız.
SocketChannel ch = ...;
ch.pipeline().addLast(new IdleStateHandler(45,0,0));
Frılatılan event'i yakalamak için şöyle yaparız.
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
  if (evt instanceof IdleStateEvent) {
    log.trace("App timeout Closing.", ((IdleStateEvent) evt).state());
    ctx.close();
  } else {
    ctx.fireUserEventTriggered(evt);
  }
}
ReadTimeoutHandler
Giriş
IdleStateHandler sınıfından kalıtır.
constructor
Şöyle yaparız.
Bootstrap b = new Bootstrap();
b.option(ChannelOption.TCP_NODELAY, true);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.group(new NioEventLoopGroup());
b.channel(NioSocketChannel.class);
b.handler(new ReadTimeoutHandler(50));

InetSocketAddress sa = new InetSocketAddress("...", 25454);
ChannelFuture f = b.connect(sa.getAddress(), sa.getPort()).sync();
Channel chan = f.channel();
//Channel becomes inactive after 30 seconds
} catch (Exception e) {
  e.printStackTrace();
}
PendingWriteQueue Sınıfı
Giriş
Şu satırı dahil ederiz.
import io.netty.channel.PendingWriteQueue;
constructor
Şöyle yaparız.
private PendingWriteQueue queue;


@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
  this.queue = new PendingWriteQueue(ctx);
}
add metodu
Şöyle yaparız.
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
throws Exception {
  this.queue.add(msg, promise);
  ...
}
removeAndWriteAll metodu
Şöyle yaparız.
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  // Send everything
  this.queue.removeAndWriteAll();
  super.channelInactive(ctx);
}
SimpleChannelInboundHandler Sınıfı
Giriş
Şu satırı dahil ederiz
import io.netty.channel.SimpleChannelInboundHandlerAdapter;
ChannelInboundHandlerAdapter'dan kalıtır ve mesaj tipini tanımlamaya izin verir.

channelRead0 metodu
Şöyle yaparız.
public class MyBusinessLogicHandler extends SimpleChannelInboundHandler<MyModel>{
  public void channelRead0(ChannelHandlerContext ctx, Packet msg){
    Packet rslt = null;
    //Do some complicated business logic
    ctx.write(rslt);
  }
}
exceptionCaught metodu
Genellikle hata loglanır ve channel kapatılır. Örnek ver.

messageReceived metodu
İmzası şöyle. Netty 5 ile channelRead0 metodu yerine bu metod geliyor.
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
  ...
}

Hiç yorum yok:

Yorum Gönder