系列文章
Netty中的异步任务TaskQueue与ScheduleTaskQueue
前言
本次文章主要是采用SpringBoot框架搭建一个简单的netty模型,包括一个服务端和一个客户端,通过客户端与服务端间发送消息通信,让大家快速上手netty的用法。
一、简介
在netty中I/O操作都是异步执行,所以任何的I/O调用都将立即返回。netty为我们提供了一个ChannelFuture实例,这个实例将会返回关于I/O操作结果或者状态。我们可以通过 addListener()为ChannelFuture添加监听器,这样当相关的操作执行结束之后就会发送消息给监听器。
下图为channelFuture状态关系对应图
可以看出一个I/O操作执行完成之前的状态为左侧表示的非完成、非成功、非取消、cause为null
一个I/O操作执行完毕之后会存在三种状态成功、失败、被取消
常见的事件监听方法如下:
- 通过 isDone() 方法来判断当前操作是否完成;
- 通过 isSuccess() 方法来判断已完成的操作是否成功;
- 通过 cause() 方法来获取已完成的操作的失败原因;
- 通过 isCancelled() 方法来判断已完成的操作是否被取消;
二、实战演示
2.1 服务端代码
package com.example.demo;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
/**
* @ClassName
* @Description netty服务端
* @Author zhiguo.zheng
* @Date 2020/10/27 15:37
**/
@Slf4j
public class NettyServer {
public static void main(String[] args) throws InterruptedException {
// 创建BossGroup和WorkerGroup
// boss处理连接请求
// worker和客户端进行业务处理
// 二者都是无限循环
// 如果不指定数量,默认是cpu的核数*2
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
// 创建服务器端启动对象
ServerBootstrap bootstrap = new ServerBootstrap();
// 使用链式编程进行设置
bootstrap.group(bossGroup, workerGroup) //设置两个线程组
.channel(NioServerSocketChannel.class) //使用NioSocketChannel作为服务器的通道实现
.option(ChannelOption.SO_BACKLOG, 128) //设置线程队列的连接数
.childOption(ChannelOption.SO_KEEPALIVE, true) //
.childHandler(new ChannelInitializer<SocketChannel>() {
// 为pipline设置处理器
@Override protected void initChannel(SocketChannel socketChannel) throws Exception {
// 这里先暂时设置为null,不涉及本次要演示的功能
socketChannel.pipeline().addLast(null);
}
});
log.info("Server---------服务端已就绪");
// 绑定一个端口并同步
int port = 6888;
ChannelFuture channelFuture = bootstrap.bind(port).sync();
// 注册监听器
channelFuture.addListener(new ChannelFutureListener() {
@Override public void operationComplete(ChannelFuture channelFuture) throws Exception {
if (channelFuture.isSuccess()) {
log.info("Server---------绑定端口isSuccess()=true");
} else {
log.info("Server---------绑定端口isSuccess()=false");
}
if (channelFuture.isDone()) {
log.info("Server---------绑定端口isDone()=true");
} else {
log.info("Server---------绑定端口isDone()=false");
}
log.info("Server---------绑定端口cause()="+String.valueOf(channelFuture.cause()));
}
});
// 监听关闭通道的动作
channelFuture.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
三、运行截图
启动服务端可以看到对于绑定端口操作监听到的执行结果,和channelFuture状态关系对应图中右侧的成功状态一致