Netty笔记(十一) 在EventLoop动态注册或注销Channel

    Netty的EventLoop,可以动态的注册跟注销Channel, 注销后的Channel不会在EventLoop中执行相应事件。也可以重新注册Channel,让其加入EventLoop中执行。

    其可以解决问题有:

    一、我们系统其他模块用到相应Socket操作,前不基于netty,我们希望让其融合进Socket。在Netty的Channel有构造器可传入Socket API进行Wapper包装。从而可以注册到我们已有的Netty的EventLoop中执行。

Socket API

Socket mySocket = new Socket("www.manning.com", 80); #1
// Perform some operations on the Socket
... #2
SocketChannel ch = new OioSocketChannel(mySocket); #3
EventLoopGroup group = ...;
ChannelFuture registerFuture = group.register(ch); #4
...
// Deregister from EventLoop again.
ChannelFuture deregisterFuture = ch.deregister(); #5
NIO SocketChannel API

java.nio.channels.SocketChannel mySocket =
java.nio.channels.SocketChannel.open(); #1
// Perform some operations on the java.nio SocketChannel
... #2
SocketChannel ch = new NioSocketChannel(mySocket); #3
EventLoopGroup group = ...;
ChannelFuture registerFuture = group.register(ch); #4
...
// Deregister from EventLoop again.
ChannelFuture deregisterFuture = ch.deregister(); #5
    二、暂停一个Channel的执行。若些Channel非常耗资源尤其I/O资源,系统也非常繁忙,撑不住了,我们让他先歇会,待系统没那么繁忙的时机再将其注册进来,加入EventLoop中执行各种事件任务。

下面程序当第一次接收到数据,就让他从EventLoop中移除,让他自己玩去,然后处理完毕再加入EventLoop中。

EventLoopGroup group = new NioEventLoopGroup(); #1
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class) #2
.handler(new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx,
ByteBuf byteBuf) throws Exception {
ctx.pipeline().remove(this);
ctx.deregister(); #3
}
});
ChannelFuture future = bootstrap.connect(
new InetSocketAddress("www.manning.com", 80)).sync();
// Do something which takes some amount of time
...
// Register channel again on eventloop
Channel channel = future.channel();
group.register(channel).addListener(new ChannelFutureListener() { #4
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
System.out.println("Channel registered");
} else {
System.err.println("Register Channel on EventLoop failed");
future.cause().printStackTrace();
}
}
});
    三、系统可以有多个EventLoop,当一个EventLoop繁忙,我们将其加入到另一个EventLoop中处理。

EventLoopGroup group = new NioEventLoopGroup(); #1
final EventLoopGroup group2 = new NioEventLoopGroup(); #2
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class) #3
.handler(new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx,
ByteBuf byteBuf) throws Exception {
ctx.pipeline().remove(this);
ChannelFuture cf = ctx.deregister(); #4
cf.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
group2.register(future.channel()); #5
}
});
}
});
ChannelFuture future = bootstrap.connect(
new InetSocketAddress("www.manning.com", 80));
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture)
throws Exception {
if (channelFuture.isSuccess()) {
System.out.println("Connection established");
} else {
System.err.println("Connection attempt failed");
channelFuture.cause().printStackTrace();
}
}
});




你可能感兴趣的:(Netty笔记(十一) 在EventLoop动态注册或注销Channel)