异步模式
- 与同步相对,当调用发出后,调用者不能立即得到结果,当任务处理者在任务处理完成后,通过回调的方式通知调用者
- netty使用future-listener机制:future和callback。假设执行一个耗时方法,等待方法的返回并不可取。那么可以在调用方法后,立马返回一个future,后续通过future去监控方法的处理状态,callback就是回调;
##注册监听器代码 使用方法还有isDone、getCause、isCancelled
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workGroup).channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new HelloServerInHandler());
}
}).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(port).sync();
f.addListener(future -> {
if (f.isSuccess()){
System.out.println("监听端口成功");
}
});
f.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
workGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
核心组件
- Bootstrap、ServerBootstrap
Bootstrap是客户端的启动引导类、ServerBootstrap是服务端的启动引导类
- public B group(EventLoopGroup group) 设置EventLoopGroup
- public B channel(Class<? extends C> channelClass)设置通道实现(NioServerSocketChannel.class、NioSocketChannel.class)
- public B option(ChannelOption option, T value)给channel添加配置
- public B handler(ChannelHandler handler)设置channel的业务处理类,对于服务端handler表示给bossgroup设置处理类,childHandler表示给workergroup设置处理类
- public ChannelFuture bind(int inetPort)设置绑定端口(服务端)
- public ChannelFuture connect(String inetHost, int inetPort)连接服务器(客户端)
- future、channelFuture:netty的io操作通过future、channelFuture实现异步,当任务执行完成会自动触发注册的监听事件
- Channel channel(),返回正在进行io操作的通道
- ChannelFuture sync(),等待异步操作执行完毕
- channel:netty通信组件,用于执行网络io操作。channel可以获得当前通道状态及通道参数配置(缓冲区大小)。调用会立即返回一个channelfuture,用于回调通知。
常用的channel类型
- NioSocketChannel,异步客户端tcp 连接
- NioServerSocketChannel,异步的服务端tcp 连接
- NioDatagramChannel,异步的udp 连接
- NioSctpChannel,异步的sctp连接
- selector:io多路复用选择器,一个线程监听多个连接channel事件
- channelHandler及其实现类:处理io操作,并将其转发到channelpipeline(业务链)中的下一个程序
- public void channelActive(ChannelHandlerContext ctx) throws Exception 通道就绪事件
- public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception 通道读取数据事件
- public void channelReadComplete(ChannelHandlerContext ctx) throws Exception 数据读取完毕事件
- pipeline和channelpipeline:channelpipeline是handler的集合,负责处理inbound和outbound事件和操作。in类型是入栈,out类型是出栈 执行顺序是不一样的
ChannelHandlerContext
- 保存有channel相关的所有上下文信息,同时关联一个channelHandler对象,即一个ChannelHandlerContext包含一个具体的事件处理器handler也绑定有对应的pipeline和channel信息
常用方法
- ChannelFuture close() ,关闭通道
- ChannelHandlerContext flush(),刷新
- ChannelFuture writeAndFlush(Object msg) 将数据写到channelpipeline中,由下一个handler处理(出栈)
ChannelOption
- ChannelOption.SO_BACKLOG: 对应tcp/ip协议listen函数的backlog参数,用来初始化服务器可连接队列大小
- ChannelOption.SO_KEEPALIVE:一直保持连接活动状态
心跳机制
IdleStateHandler:netty提供的handler处理器,用于心跳检测。
public IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime,TimeUnit unit)
初始化处理器:readerIdleTime:表示多长时间没有读,会发送心跳检测包、writerIdleTIme:表示多长时间没有写,会发送心跳检测包、allIdleTime:表示多长时间没有读写,会发送心跳检测包
当IdleStateHandler触发后,会立即传递给pipeline,交给下一个handler处理,触发下一个处理器的userEventTrigger,通过此方法可以自定义超时处理
public class MyServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent) ctx;
String eventType = null;
switch (event.state()) {
case ALL_IDLE:
eventType = "读写空闲";
break;
case READER_IDLE:
eventType = "读空闲";
break;
case WRITER_IDLE:
eventType = "写空闲";
break;
}
System.out.println(ctx.channel().remoteAddress()+"---超时时间---"+eventType);
}
}
}