netty pipeline事件传播
相关类与接口
ChannelHandler
public interface ChannelHandler {
void handlerAdded(ChannelHandlerContext var1) throws Exception;
void handlerRemoved(ChannelHandlerContext var1) throws Exception;
/** @deprecated */
@Deprecated
void exceptionCaught(ChannelHandlerContext var1, Throwable var2) throws Exception;
@Inherited
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Sharable {
}
}
ChannelInboundHandler:inbound事件,从head往tail传播
public interface ChannelInboundHandler extends ChannelHandler {
void channelRegistered(ChannelHandlerContext var1) throws Exception;
void channelUnregistered(ChannelHandlerContext var1) throws Exception;
void channelActive(ChannelHandlerContext var1) throws Exception;
void channelInactive(ChannelHandlerContext var1) throws Exception;
void channelRead(ChannelHandlerContext var1, Object var2) throws Exception;
void channelReadComplete(ChannelHandlerContext var1) throws Exception;
void userEventTriggered(ChannelHandlerContext var1, Object var2) throws Exception;
void channelWritabilityChanged(ChannelHandlerContext var1) throws Exception;
void exceptionCaught(ChannelHandlerContext var1, Throwable var2) throws Exception;
}
ChannelOutboundHandler:outbound事件,从tail到head传播
public interface ChannelOutboundHandler extends ChannelHandler {
void bind(ChannelHandlerContext var1, SocketAddress var2, ChannelPromise var3) throws Exception;
void connect(ChannelHandlerContext var1, SocketAddress var2, SocketAddress var3, ChannelPromise var4) throws Exception;
void disconnect(ChannelHandlerContext var1, ChannelPromise var2) throws Exception;
void close(ChannelHandlerContext var1, ChannelPromise var2) throws Exception;
void deregister(ChannelHandlerContext var1, ChannelPromise var2) throws Exception;
void read(ChannelHandlerContext var1) throws Exception; //read事件
void write(ChannelHandlerContext var1, Object var2, ChannelPromise var3) throws Exception;
//write事件,本身不会执行写操作
void flush(ChannelHandlerContext var1) throws Exception; //刷新事件
}
ChannelHandlerContext
public interface ChannelHandlerContext extends AttributeMap, ChannelInboundInvoker, ChannelOutboundInvoker {
Channel channel();
ChannelHandler handler();
EventExecutor executor();
String name();
boolean isRemoved();
ChannelHandlerContext fireChannelRegistered();
ChannelHandlerContext fireChannelUnregistered();
ChannelHandlerContext fireChannelActive();
ChannelHandlerContext fireChannelInactive();
ChannelHandlerContext fireExceptionCaught(Throwable var1);
ChannelHandlerContext fireUserEventTriggered(Object var1);
ChannelHandlerContext fireChannelRead(Object var1);
ChannelHandlerContext fireChannelReadComplete();
ChannelHandlerContext fireChannelWritabilityChanged();
ChannelHandlerContext read();
ChannelHandlerContext flush();
ChannelPipeline pipeline();
ByteBufAllocator alloc();
/** @deprecated */
@Deprecated
<T> Attribute<T> attr(AttributeKey<T> var1);
/** @deprecated */
@Deprecated
<T> boolean hasAttr(AttributeKey<T> var1);
}
AttributeMap
public interface AttributeMap {
<T> Attribute<T> attr(AttributeKey<T> var1);
<T> boolean hasAttr(AttributeKey<T> var1);
}
ChannelInboundInvoker:触发inbound事件
public interface ChannelInboundInvoker {
ChannelInboundInvoker fireChannelRegistered();
ChannelInboundInvoker fireChannelUnregistered();
ChannelInboundInvoker fireChannelActive();
ChannelInboundInvoker fireChannelInactive();
ChannelInboundInvoker fireExceptionCaught(Throwable var1);
ChannelInboundInvoker fireUserEventTriggered(Object var1);
ChannelInboundInvoker fireChannelRead(Object var1);
ChannelInboundInvoker fireChannelReadComplete();
ChannelInboundInvoker fireChannelWritabilityChanged();
}
ChannelOutboundInvoker:触发outbound事件
public interface ChannelOutboundInvoker {
ChannelFuture bind(SocketAddress var1);
ChannelFuture bind(SocketAddress var1, ChannelPromise var2);
ChannelFuture connect(SocketAddress var1);
ChannelFuture connect(SocketAddress var1, SocketAddress var2);
ChannelFuture connect(SocketAddress var1, ChannelPromise var2);
ChannelFuture connect(SocketAddress var1, SocketAddress var2, ChannelPromise var3);
ChannelFuture disconnect();
ChannelFuture disconnect(ChannelPromise var1);
ChannelFuture close();
ChannelFuture close(ChannelPromise var1);
ChannelFuture deregister();
ChannelFuture deregister(ChannelPromise var1);
ChannelOutboundInvoker read();
ChannelFuture write(Object var1);
ChannelFuture write(Object var1, ChannelPromise var2);
ChannelOutboundInvoker flush();
ChannelFuture writeAndFlush(Object var1, ChannelPromise var2);
ChannelFuture writeAndFlush(Object var1);
ChannelPromise newPromise();
ChannelProgressivePromise newProgressivePromise();
ChannelFuture newSucceededFuture();
ChannelFuture newFailedFuture(Throwable var1);
ChannelPromise voidPromise();
}
使用示例
**********
服务端
CustomServerInboundHandler
public class CustomServerInboundHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("CustomServerInboundHandler:"+msg);
ctx.fireChannelRead(msg);
}
}
CustomServerInboundHandler2
public class CustomServerInboundHandler2 extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("CustomServerInboundHandler2:"+msg);
ctx.fireChannelRead(msg);
}
}
CustomServerInboundHandler3
public class CustomServerInboundHandler3 extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("CustomServerInboundHandler3:"+msg);
ctx.fireChannelRead(msg);
}
}
CustomServerOutboundHandler
public class CustomServerOutboundHandler extends ChannelOutboundHandlerAdapter {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
System.out.println("CustomServerOutboundHandler write:"+msg);
//ctx.channel().writeAndFlush("CustomServerOutboundHandler");
ctx.write(msg);
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
//CustomServerOutboundHandler添加到pipeline后执行
ctx.executor().schedule(()->{
ctx.channel().writeAndFlush("服务端返回的信息");
},3, TimeUnit.SECONDS);
}
}
CustomServerOutboundHandler2
public class CustomServerOutboundHandler2 extends ChannelOutboundHandlerAdapter {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
System.out.println("CustomServerOutboundHandler2 write:"+msg);
//ctx.channel().writeAndFlush("CustomServerOutboundHandler2");
ctx.write(msg);
}
}
CustomServerOutboundHandler3
public class CustomServerOutboundHandler3 extends ChannelOutboundHandlerAdapter {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
System.out.println("CustomServerOutboundHandler3 write:"+msg);
//ctx.channel().writeAndFlush("CustomServerOutboundHandler3");
ctx.write(msg);
}
}
NettyServer
public class NettyServer {
public static void startServer(int port){
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline channelPipeline = socketChannel.pipeline();
channelPipeline.addLast(new StringDecoder());
channelPipeline.addLast(new StringEncoder());
channelPipeline.addLast("inbound",new CustomServerInboundHandler());
channelPipeline.addLast("inbound2",new CustomServerInboundHandler2());
channelPipeline.addLast("inbound3",new CustomServerInboundHandler3());
channelPipeline.addLast("outbound",new CustomServerOutboundHandler());
channelPipeline.addLast("outbound2",new CustomServerOutboundHandler2());
channelPipeline.addLast("outbound3",new CustomServerOutboundHandler3());
}
});
ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
channelFuture.channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) {
startServer(8000);
}
}
**********
客户端
CustomClientHandler
public class CustomClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("客户端开始发送数据");
ctx.channel().writeAndFlush("客户端向服务端发送数据");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("客户端读取的响应数据:"+msg);
}
}
NettyClient
public class NettyClient {
public static void connect(String host, int port){
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline channelPipeline = socketChannel.pipeline();
channelPipeline.addLast(new StringDecoder());
channelPipeline.addLast(new StringEncoder());
channelPipeline.addLast("custom",new CustomClientHandler());
}
});
ChannelFuture channelFuture = bootstrap.connect(host,port).sync();
channelFuture.channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}finally {
eventLoopGroup.shutdownGracefully();
}
}
public static void main(String[] args) {
String host = "localhost";
int port = 8000;
connect(host, port);
}
}
**********
使用测试
点击运行后,服务端输出:
18:08:24.446 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
18:08:24.446 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.chunkSize: 32
18:08:24.446 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.blocking: false
18:08:24.453 [nioEventLoopGroup-3-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkAccessible: true
18:08:24.453 [nioEventLoopGroup-3-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
18:08:24.454 [nioEventLoopGroup-3-1] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@31000a34
CustomServerInboundHandler:客户端向服务端发送数据
CustomServerInboundHandler2:客户端向服务端发送数据
CustomServerInboundHandler3:客户端向服务端发送数据
18:08:24.472 [nioEventLoopGroup-3-1] DEBUG io.netty.channel.DefaultChannelPipeline - Discarded inbound message 客户端向服务端发送数据 that reached at the tail of the pipeline. Please check your pipeline configuration.
18:08:24.480 [nioEventLoopGroup-3-1] DEBUG io.netty.channel.DefaultChannelPipeline - Discarded message pipeline : [StringDecoder#0, StringEncoder#0, inbound, inbound2, inbound3, outbound, outbound2, outbound3, DefaultChannelPipeline$TailContext#0]. Channel : [id: 0xdb2ba244, L:/127.0.0.1:8000 - R:/127.0.0.1:51533].
CustomServerOutboundHandler3 write:服务端返回的信息
CustomServerOutboundHandler2 write:服务端返回的信息
CustomServerOutboundHandler write:服务端返回的信息
点击运行后,客户端输出:
18:08:24.254 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimIntervalMillis: 0
18:08:24.254 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.useCacheForAllThreads: false
18:08:24.254 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedByteBuffersPerChunk: 1023
18:08:24.265 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.allocator.type: pooled
18:08:24.265 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.threadLocalDirectBufferSize: 0
18:08:24.266 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.maxThreadLocalCharBufferSize: 16384
客户端开始发送数据
18:08:24.379 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxCapacityPerThread: 4096
18:08:24.379 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
18:08:24.379 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.chunkSize: 32
18:08:24.379 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.blocking: false
18:08:24.389 [nioEventLoopGroup-2-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkAccessible: true
18:08:24.389 [nioEventLoopGroup-2-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
18:08:24.390 [nioEventLoopGroup-2-1] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@7ac35e02
客户端读取的响应数据:服务端返回的信息