1 阻塞IO ,阻塞异步IO,非阻塞异步IO
首先学习netty ,那就必须对阻塞IO ,阻塞异步IO,非阻塞异步IO有一个了解,可以参考https://www.ibm.com/developerworks/cn/linux/l-async/
2 netty的架构
netty吸收了多种协议( FTP,SMTP,HTTP,WebSocket,SPDY,二进制、文本)实现的经验,帮助实现了构建快速构建一个高性能、稳定、以扩展的,基于NIO的客户端、服务端框架,其体系结构如下:
3 核心类分析
1) EventLoop类
在netty中的体系架构中的位置
EventLoop是基于current包中的ScheduledExecutorService来做线程调度的:下面是EventLoop的源码分析:
EventLoop
public interface EventLoop extends EventExecutor, EventLoopGroup {
@Override
EventLoopGroup parent();
}
eventLoop继承EventLoopGroup,EventLoopGroup的源码如下:
EventLoopGroup
public interface EventLoopGroup extends EventExecutorGroup {
/**
* 下一个事件执行器(EventExcutor)
*/
@Override
EventLoop next();
/**
* 将一个Channel注册给EventExecutor,返回一个ChannelFuture
*/
ChannelFuture register(Channel channel);
/**
* Channel注册给EventExecutor,ChannelPromise是一个可以写入的ChannelFuture* 返回一个ChannelFuture
*/
ChannelFuture register(Channel channel, ChannelPromise promise);
}
EventExecutor
public interface EventExecutor extends EventExecutorGroup {
/**
* 返回指向自己的引用
*/
@Override
EventExecutor next();
/**
* 返回父类EventExecutorGroup
*/
EventExecutorGroup parent();
/**
* 判断一个线程是否在ScheduledExecutorService的调度中
*/
boolean inEventLoop();
/**
* 判断一个线程是否在ScheduleExecutorService的调度中
*/
boolean inEventLoop(Thread thread);
<V> Promise<V> newPromise();
<V> ProgressivePromise<V> newProgressivePromise();
<V> Future<V> newSucceededFuture(V result);
<V> Future<V> newFailedFuture(Throwable cause);
}
EventLoop下就有EmbededEventLoop和抽象类SingleThreadEventLoop
SingleThreadEventLoop
根据字面意思,可以看出管理event的线程是单一的。他的子类有AioEventLoop,LocalEventLoop,NioEventLoop,OioEventLoopSingleThreadEventLoopImp等。
MultithreadEventLoopGroupl
实际上就是SingleThreadEventLoop
详情可以参考:
http://airu.iteye.com/blog/1749331
2) ChannelHandler类
public interface ChannelHandler {
/**
* Gets called after the {@link ChannelHandler} was added to the actual context and it's ready to handle events.
*/
void handlerAdded(ChannelHandlerContext ctx) throws Exception;
/**
* Gets called after the {@link ChannelHandler} was removed from the actual context and it doesn't handle events
* anymore.
*/
void handlerRemoved(ChannelHandlerContext ctx) throws Exception;
/**
* Gets called if a {@link Throwable} was thrown.
*
* @deprecated Will be removed in the future and only {@link ChannelInboundHandler} will receive
* exceptionCaught events. For {@link ChannelOutboundHandler} the {@link ChannelPromise}
* must be failed.
*/
@Deprecated
void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
/**
* Indicates that the same instance of the annotated {@link ChannelHandler}
* can be added to one or more {@link ChannelPipeline}s multiple times
* without a race condition.
* <p>
* If this annotation is not specified, you have to create a new handler
* instance every time you add it to a pipeline because it has unshared
* state such as member variables.
* <p>
* This annotation is provided for documentation purpose, just like
* <a href="http://www.javaconcurrencyinpractice.com/annotations/doc/">the JCIP annotations</a>.
*/
@Inherited
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Sharable {
// no value
}
}
每一个ChannelHandler添加都ChannelPipeline中都需要创建和绑定一个ChannelHandlerContext,如图所示:
ChannelHandlerContext类
public interface ChannelHandlerContext
extends AttributeMap, ChannelPropertyAccess,
ChannelInboundInvoker, ChannelOutboundInvoker {
/**
* Return the {@link Channel} which is bound to the {@link ChannelHandlerContext}.
*/
Channel channel();
/**
* The {@link EventExecutor} that is used to dispatch the events. This can also be used to directly
* submit tasks that get executed in the event loop. For more information please refer to the
* {@link EventExecutor} javadoc.
*/
EventExecutor executor();
/**
* The unique name of the {@link ChannelHandlerContext}.The name was used when then {@link ChannelHandler}
* was added to the {@link ChannelPipeline}. This name can also be used to access the registered
* {@link ChannelHandler} from the {@link ChannelPipeline}.
*/
String name();
/**
* The {@link ChannelHandler} that is bound this {@link ChannelHandlerContext}.
*/
ChannelHandler handler();
/**
* Return {@code true} if the {@link ChannelHandler} which belongs to this {@link ChannelHandler} was removed
* from the {@link ChannelPipeline}. Note that this method is only meant to be called from with in the
* {@link EventLoop}.
*/
boolean isRemoved();
@Override
ChannelHandlerContext fireChannelRegistered();
@Override
@Deprecated
ChannelHandlerContext fireChannelUnregistered();
@Override
ChannelHandlerContext fireChannelActive();
@Override
ChannelHandlerContext fireChannelInactive();
@Override
ChannelHandlerContext fireExceptionCaught(Throwable cause);
@Override
ChannelHandlerContext fireUserEventTriggered(Object event);
@Override
ChannelHandlerContext fireChannelRead(Object msg);
@Override
ChannelHandlerContext fireChannelReadComplete();
@Override
ChannelHandlerContext fireChannelWritabilityChanged();
@Override
ChannelHandlerContext flush();
}
这里的ChannelInboundInvoker接口基本上就是拥有通知Channel上的各种事件的能力,二ChannelOutboundInvoker则是具备了向管道外写数据,连接等功能。注意返回值都是ChannelFuture这就说明这些操作都是异步的。
总之ChannelOutboundInvoker是Channel,ChannelhandlerContext, ChannelPipeline的父接口。
对于ChannelHandlerContext来说,基本上就是对传输过程中的各个方面的管理器。包括ChannelHandler的注册销毁等等。
每个ChannelHander都是有方向性的。这里的方向性,也就是管道中inbound和outbound的意思。所以ChannelHander的两个子接口 ChannelOperationHandler 也就是outbound 和ChannelStateHandler 也就是inbound。围绕着in与out,又催生出子接口 ChannelOutboundHandler 和 ChannelInboundHandler。比较常用的子类:
ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapter
public class ChannelInboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelInboundHandler {
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelRegistered();
}
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelUnregistered();
}
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelActive();
}
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelInactive();
}
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.fireChannelRead(msg);
}
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelReadComplete();
}
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
ctx.fireUserEventTriggered(evt);
}
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelWritabilityChanged();
}
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
ctx.fireExceptionCaught(cause);
}
}
可以根据自己需要重写对应的方法,(方法的使用,请查阅api),ChannelOutboundHandlerAdapter也类似
ChannelPipeline类
ChannelPipeline的作用看如下图就可以明白了
Buffer类
Bootstrap类
Bootstrap 和 BootstrapServer都是继承AbstractBootstrap
查看AbstractBootstrap的变量定义
private volatile EventLoopGroup group;
private volatile ChannelFactory<? extends C> channelFactory;
private volatile SocketAddress localAddress;
private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();
private final Map<AttributeKey<?>, Object> attrs = new LinkedHashMap<AttributeKey<?>, Object>();
private volatile ChannelHandler handler;
一个事件组,netty是事件驱动的,事件组应该是各种事件的容器;一个Channel工厂,这自然是用来生产Channel的(这里应该有各种管道。比如服务端的和客户端的就不一样) ;SocketAddress是本地地址 options 是这个管道的属性集合 attrs 是属性键集合(这个搞不懂,先放下); ChannelHandler 用于处理管道的各种事件吧。
具体方法的含义如下:
1, public B group(EventLoopGroup group)
这个函数简单,设置group,注意如果传入参数为空,或者原先的group不为空都要抛出异常。然后,返回自身 ,注意泛型 B
2, public B channel(Class<? extends Channel> channelClass)
这个类用来创建一个Channel实例,使用了ChannelFactory。使用工厂模式推迟具体实例创建到子类中。这里可以看做一个工厂设置
3, public B channelFactory(ChannelFactory factory)
2调用了3,
4,public B localAddress(SocketAddress localAddress)
绑定本地地址
5, public B localAddress(int port)
同样绑定本地地址
6, public B localAddress(String host, int port)
同4,5
7, public B localAddress(InetAddress host, int port)
通4,5,6
8, public <T> B option(ChannelOption<T> option, T value)
实例化Channel时的参数。如果 value为null,这个option被remove掉。
9, public <T> B attr(Attribute<T> key, T value)
实例化Channel后Channel的属性value为null时,attr被remove掉。
10, public void shutdown()
这里关闭的是EventLoopGroup
11, protected void validate()
这里变protected了,用于同类的参数验证。子类如果复写,需要使用super先调用父类
12,protected final void validate(ChannelFuture future)
验证了future不为null,然后调用11, 不可以被复写
13,public ChannelFuture bind()
创建一个Channel并且绑定
14,public B handler(ChannelHandler handler)
handler不能为null,设置handler
15,public static boolean ensureOpen(ChannelFuture future)
确保future中的channel为open状态,否则futrue设置为失败ChannelException
16,public abstract ChannelFuture bind(ChannelFuture future)
把Channel绑定到给定的ChannelFactory上。抽象方法,意味着需要具体的Channel
Bootstrap中多了两个变量
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Bootstrap.class);
private volatile SocketAddress remoteAddress;
BootstrapServer类
private final Map<ChannelOption<?>, Object> childOptions = new LinkedHashMap<ChannelOption<?>, Object>();
private final Map<AttributeKey<?>, Object> childAttrs = new LinkedHashMap<AttributeKey<?>, Object>();
private volatile EventLoopGroup childGroup;
private volatile ChannelHandler childHandler;
/**
* Set the {@link EventLoopGroup} for the parent (acceptor) and the child (client). These
* {@link EventLoopGroup}'s are used to handle all the events and IO for {@link SocketChannel} and
* {@link Channel}'s.
*/
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
super.group(parentGroup);
if (childGroup == null) {
throw new NullPointerException("childGroup");
}
if (this.childGroup != null) {
throw new IllegalStateException("childGroup set already");
}
this.childGroup = childGroup;
return this;
}
- 大小: 59.4 KB
- 大小: 69.7 KB
- 大小: 48.5 KB
- 大小: 46.4 KB
分享到:
相关推荐
Netty入门教程文档 Netty是Java的网络编程框架,广泛应用于数据采集服务中,本文将对Netty的基本概念和应用进行详细介绍,并将其与ETL技术结合,讲解如何使用Netty进行数据流转和处理。 1. ETL概述 ETL(Extract...
### Netty 入门与实战:仿写微信 IM 即时通讯系统 #### 一、引言 随着移动互联网技术的飞速发展,即时通讯(IM)应用已成为人们日常生活中不可或缺的一部分。微信作为中国最成功的即时通讯软件之一,其背后的架构和...
### Netty入门与实战:仿写微信IM即时通讯系统 #### 一、引言 随着移动互联网技术的飞速发展,即时通讯(IM)系统已成为人们日常生活中不可或缺的一部分。微信作为国内最受欢迎的即时通讯软件之一,其高效稳定的通信...
Netty 入门与实战:仿写微信 IM 即时通讯系统,掘金小册子,netty教程。章节齐全无缺失,排版非常不错。 1.仿微信IM系统简介 1 2.Netty是什么? 2 3.服务端启动流程 8 4.客户端启动流程 11 5.实战:客户端与服务端双向...
《Netty 入门与实战:仿写微信 IM 即时通讯系统》是一本深入浅出的教程,旨在帮助读者掌握使用Netty构建高效、稳定、高性能的即时通讯系统的方法。通过模仿微信IM的实现,本书将理论知识与实践案例相结合,使读者...
根据提供的文件信息“netty入门到精通”,我们可以深入探讨Netty框架的相关知识点,包括其基本概念、核心组件、应用场景以及如何逐步掌握这项技术。 ### Netty框架简介 Netty是一款高性能、异步事件驱动的网络应用...
在本文中,我们将深入探讨Netty框架,并通过实战项目——仿写微信IM即时通讯系统,来深入了解其在高性能网络应用中的应用。Netty是Java领域中一个高效的异步事件驱动的网络应用程序框架,它为快速开发可维护的高性能...
文件"72-第2章_20-netty入门-jdk-future-480P 清晰-AVC.Cover.jpg"、"73-第2章_21-netty入门-netty-future-480P 清晰-AVC.Cover.jpg"和"74-第2章_22-netty入门-netty-promise-480P 清晰-AVC.Cover.jpg"详细解释了...
Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。这个框架在Java领域广泛应用于构建高并发、低延迟的网络应用,如分布式系统、游戏服务器、金融交易系统等。...
本工程采用maven+netty4.1.0+PrefixedStringDecoder+json技术,包括客户端和服务端。先运行服务端SampleServer,再去等客户端SampleClient。示例中发的是心跳包,其中消息格式定义为msgType + msgNo + content(json...
这个“netty入门案例.zip”文件提供了一个简单的 Netty 应用示例,旨在帮助初学者快速理解并掌握 Netty 的基本概念和使用方法。下面将详细介绍这个入门案例中的关键知识点。 首先,Netty 的核心是其 ChannelHandler...
在学习"Netty入门Reactor示例"时,你可以按照以下步骤进行: 1. **创建服务器端:** - 首先,你需要创建一个ServerBootstrap实例,配置BossGroup和WorkerGroup。 - 然后,添加自定义的...
这个“netty入门例子”旨在帮助初学者理解Netty的基本用法和特性,而不是简单地翻译官方文档,它提供了几个开发模板,以便于深入理解Netty中的消息异步通信机制和TCP通信的封装。 首先,Netty的核心是它的异步模型...
这个“netty入门与实战-netty-learn.zip”文件包含了学习 Netty 的资源,帮助初学者理解并掌握这个强大的网络库。Netty-learn-master 可能是一个包含源代码、教程文档或者示例项目的目录。 Netty 的核心概念: 1. ...
这个压缩包“掘金-Netty 入门与实战-netty-demo.zip”包含了关于 Netty 的入门教程和实战示例,特别是通过 "netty-demo-pipeline-channelHandler" 这个文件名我们可以推测,它可能包含了一个展示 Netty ...
近百节视频详细讲解,需要的小伙伴自行百度网盘下载,... Netty 入门 1. 概述 2. Hello World 3. 组件 4. 双向通信 三. Netty 进阶 1. 粘包与半包 2. 协议设计与解析 3. 聊天室案例 四. 优化与源码 1. 优化 2. 源码分析