1.BIO,NIO,AIO区别
2.netty的Reactor模型
主从模式的编程实现:
public class HelloServer {
public static void main(String[] args) {
EventLoopGroup bossGroup = new NioEventLoopGroup();// 主线程组,专门管理客户的连接
EventLoopGroup workGrop = new NioEventLoopGroup();// 从线程组,用来管业务的完成
try {
// serverBootstrap就是服务器启动类
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workGrop)
.channel(NioServerSocketChannel.class)// NIO的channel类型
.childHandler(null); // 此处可以定从线程组的任务
// 启动serverBootstrap,绑定8088端口,启动方式是同步的方式
ChannelFuture channelFuture = serverBootstrap.bind(8088).sync();
// 监听关闭的channel,设置位同步方式
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
// 关闭线程组
bossGroup.shutdownGracefully();
workGrop.shutdownGracefully();
}
}
}
3. channel和pipeline,handler之间的关系
/**
* 初始化器:channel注册后,会执行里面的相应的初始化方法
*/
public class HelloServerInit extends ChannelInitializer<SocketChannel> {
protected void initChannel(SocketChannel socketChannel) throws Exception {
// 通过socketChannel获取对应处理的管道
ChannelPipeline pipeline = socketChannel.pipeline();
// HttpServerCodec是netty自带的handler,是http协议的编码解码器
pipeline.addLast("HttpServerCodec",new HttpServerCodec());
pipeline.addLast("customHandler",new CustomHandler());
}
}
3.自定义一个http请求的handler
/**
* 自定义助手类
*/
public class CustomHandler extends SimpleChannelInboundHandler<HttpObject> {
protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject) throws Exception {
//获取channel
Channel channel = channelHandlerContext.channel();
//显示客户端远程地址
if (httpObject instanceof HttpRequest){
System.out.println(channel.localAddress());
}
// Unpooled是一个执行拷贝的工具类,copiedBuffer将"hello"字符串拷贝到一个buffer中
ByteBuf context = Unpooled.copiedBuffer("hello", CharsetUtil.UTF_8);
// 构建一个http相应
FullHttpResponse fullHttpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, context);
fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain");
fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH,context.readableBytes());
// channel的消息写到缓存区,并且flush到客户端
channelHandlerContext.writeAndFlush(fullHttpResponse);
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel。。。注册");
super.channelRegistered(ctx);
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel。。。移除");
super.channelUnregistered(ctx);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel。。。活跃");
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel。。。不活跃");
super.channelInactive(ctx);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
System.out.println("channeld读取完毕。。。");
super.channelReadComplete(ctx);
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
System.out.println("用户事件触发。。。");
super.userEventTriggered(ctx, evt);
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel可写更改");
super.channelWritabilityChanged(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("补货到异常");
super.exceptionCaught(ctx, cause);
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
System.out.println("助手类添加");
super.handlerAdded(ctx);
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
System.out.println("助手类移除");
super.handlerRemoved(ctx);
}
}
启动项目
源码: https://github.com/LUK-qianliu/netty