netty handler命名
相关类与接口
ChannelPipeline
public interface ChannelPipeline extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable<Entry<String, ChannelHandler>> {
********
add操作
ChannelPipeline addFirst(String var1, ChannelHandler var2);
ChannelPipeline addFirst(EventExecutorGroup var1, String var2, ChannelHandler var3);
ChannelPipeline addLast(String var1, ChannelHandler var2);
ChannelPipeline addLast(EventExecutorGroup var1, String var2, ChannelHandler var3);
ChannelPipeline addBefore(String var1, String var2, ChannelHandler var3);
ChannelPipeline addBefore(EventExecutorGroup var1, String var2, String var3, ChannelHandler var4);
ChannelPipeline addAfter(String var1, String var2, ChannelHandler var3);
ChannelPipeline addAfter(EventExecutorGroup var1, String var2, String var3, ChannelHandler var4);
ChannelPipeline addFirst(ChannelHandler... var1);
ChannelPipeline addFirst(EventExecutorGroup var1, ChannelHandler... var2);
ChannelPipeline addLast(ChannelHandler... var1);
ChannelPipeline addLast(EventExecutorGroup var1, ChannelHandler... var2);
********
remove操作
ChannelPipeline remove(ChannelHandler var1);
ChannelHandler remove(String var1);
<T extends ChannelHandler> T remove(Class<T> var1);
ChannelHandler removeFirst();
ChannelHandler removeLast();
********
获取handler
ChannelHandler first();
ChannelHandler last();
ChannelHandler get(String var1);
<T extends ChannelHandler> T get(Class<T> var1);
********
替换handler
ChannelPipeline replace(ChannelHandler var1, String var2, ChannelHandler var3);
ChannelHandler replace(String var1, String var2, ChannelHandler var3);
<T extends ChannelHandler> T replace(Class<T> var1, String var2, ChannelHandler var3);
********
获取context
ChannelHandlerContext firstContext();
ChannelHandlerContext lastContext();
ChannelHandlerContext context(String var1);
ChannelHandlerContext context(ChannelHandler var1);
ChannelHandlerContext context(Class<? extends ChannelHandler> var1);
********
触发事件
ChannelPipeline fireChannelRegistered();
ChannelPipeline fireChannelUnregistered();
ChannelPipeline fireChannelActive();
ChannelPipeline fireChannelInactive();
ChannelPipeline fireExceptionCaught(Throwable var1);
ChannelPipeline fireUserEventTriggered(Object var1);
ChannelPipeline fireChannelRead(Object var1);
ChannelPipeline fireChannelReadComplete();
ChannelPipeline fireChannelWritabilityChanged();
Channel channel(); //获取pileline对应的channel
List<String> names(); //获取handler name集合
Map<String, ChannelHandler> toMap(); //key为name、value为对应的handler
ChannelPipeline flush(); //刷新pipeline
}
DefaultChannelPipeline
public class DefaultChannelPipeline implements ChannelPipeline {
public final ChannelPipeline addLast(String name, ChannelHandler handler) {
return this.addLast((EventExecutorGroup)null, name, handler);
} //addLast添加handler,其余添加操作类似
public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
AbstractChannelHandlerContext newCtx;
synchronized(this) {
checkMultiplicity(handler);
newCtx = this.newContext(group, this.filterName(name, handler), handler);
//过滤name、handler,创建存的context
this.addLast0(newCtx); //添加context
if (!this.registered) {
newCtx.setAddPending();
this.callHandlerCallbackLater(newCtx, true);
return this;
}
EventExecutor executor = newCtx.executor();
if (!executor.inEventLoop()) {
this.callHandlerAddedInEventLoop(newCtx, executor);
return this;
}
}
this.callHandlerAdded0(newCtx);
return this;
}
private String filterName(String name, ChannelHandler handler) {
if (name == null) { //如果name为null,自动生成name
return this.generateName(handler);
} else { //如果不为null,检验是否重复
this.checkDuplicateName(name);
return name;
}
}
private String generateName(ChannelHandler handler) { //name生成规则
Map<Class<?>, String> cache = (Map)nameCaches.get();
Class<?> handlerType = handler.getClass();
String name = (String)cache.get(handlerType);
if (name == null) {
name = generateName0(handlerType);
cache.put(handlerType, name);
}
if (this.context0(name) != null) {
String baseName = name.substring(0, name.length() - 1);
int i = 1;
while(true) {
String newName = baseName + i;
if (this.context0(newName) == null) {
name = newName;
break;
}
++i;
}
}
return name;
}
private static String generateName0(Class<?> handlerType) {
return StringUtil.simpleClassName(handlerType) + "#0";
}
private void checkDuplicateName(String name) {
if (this.context0(name) != null) {
throw new IllegalArgumentException("Duplicate handler name: " + name);
} //handler name如果重复,直接抛出异常
}
使用示例
*********
服务端
CustomServerHandler
public class CustomServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("服务端接到客户端数据:"+msg);
ctx.channel().writeAndFlush("这是服务端向客户端发送的数据");
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
}
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("custom",new CustomServerHandler());
} //添加自定义handler,名称为custom
});
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());
} //添加自定义handler,名称为custom
});
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);
}
}
*********
使用测试
点击运行后,服务端输出:
14:46:48.733 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
14:46:48.733 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.chunkSize: 32
14:46:48.733 [nioEventLoopGroup-3-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.blocking: false
14:46:48.739 [nioEventLoopGroup-3-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkAccessible: true
14:46:48.739 [nioEventLoopGroup-3-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
14:46:48.740 [nioEventLoopGroup-3-1] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@28421cf2
服务端接到客户端数据:客户端向服务端发送数据
点击运行后,客户端输出:
14:46:48.555 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimIntervalMillis: 0
14:46:48.555 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.useCacheForAllThreads: false
14:46:48.555 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedByteBuffersPerChunk: 1023
14:46:48.571 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.allocator.type: pooled
14:46:48.571 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.threadLocalDirectBufferSize: 0
14:46:48.571 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.maxThreadLocalCharBufferSize: 16384
客户端开始发送数据
14:46:48.675 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxCapacityPerThread: 4096
14:46:48.676 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
14:46:48.676 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.chunkSize: 32
14:46:48.676 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.blocking: false
14:46:48.684 [nioEventLoopGroup-2-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkAccessible: true
14:46:48.684 [nioEventLoopGroup-2-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
14:46:48.685 [nioEventLoopGroup-2-1] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@188ebe7
客户端读取的响应数据:这是服务端向客户端发送的数据