Channel类

package io.netty.channel;

import io.netty.buffer.ByteBuf;

import io.netty.buffer.MessageBuf;

import io.netty.channel.socket.DatagramChannel;

import io.netty.channel.socket.ServerSocketChannel;

import io.netty.channel.socket.SocketChannel;

import io.netty.util.AttributeMap;

import java.net.InetSocketAddress;

import java.net.SocketAddress;

import java.nio.channels.SelectionKey;

public interface Channel extends AttributeMap, ChannelOutboundInvoker, ChannelFutureFactory, Comparable<Channel> {

Integer id();

EventLoop eventLoop();

Channel parent();

ChannelConfig config();

ChannelPipeline pipeline();

boolean isOpen();

boolean isRegistered();

boolean isActive();

ChannelMetadata metadata();

ByteBuf outboundByteBuffer();

<T> MessageBuf<T> outboundMessageBuffer();

SocketAddress localAddress();

SocketAddress remoteAddress();

ChannelFuture closeFuture();

Unsafe unsafe();

interface Unsafe {

ChannelHandlerContext directOutboundContext();

ChannelFuture voidFuture();

SocketAddress localAddress();

SocketAddress remoteAddress();

void register(EventLoop eventLoop, ChannelFuture future);

void bind(SocketAddress localAddress, ChannelFuture future);

void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelFuture future);

void disconnect(ChannelFuture future);

void close(ChannelFuture future);

void closeForcibly();

void deregister(ChannelFuture future);

void flush(ChannelFuture future);

void flushNow();

void suspendRead();

void resumeRead();

}

}

Channel类UML图.JPG

etty 4.0中,定义了Channel接口,这个接口用于连接网络的socket传输,或者具有I/O操作的组件连接。这里的I/O操作有,read,write,bind,connect
Channel接口为用户提供了:
1.   Channel的当前状态,比如:Channel是否open,或者Channel是否已经连接。
2.   Channel的参数,比如:接受的buffer大小。
3.   Channel支持的I/O操作,比如:read,write,connect,bind。
4.   注册在Channel上的ChannelPipeline,ChannelPipeline用于处理所有的I/O事件和请求。
Channel类的几个重要方法
ChannelFuture closeFuture();
所有在Netty中的I/O操作都是异步的,这就意味着任何的I/O调用都会立即返回,但是无法保证所有被调用的I/O操作到最后能够成功执行完成。closeFuture() 返回一个ChannelFuture对象, 并且告诉I/O的调用者,这个I/O调用的最后状态是succeeded,failed 或者 canceled。
void register(EventLoop eventLoop, ChannelFuture future);
在Channel中注册EventLoop和对应的ChannelFuture。

void deregister(ChannelFuture future);
在Channel中取消ChannelFuture的注册。

在Channel的层次结构中,Channel子类的实现取决于传输的具体实现。比如SocketChannel,能够被ServerSocketChannel接受,并且SocketChannel中的getParent()方法会返回ServerSocketChannel。开发者可以实现Channel接口,共享Socket连接,比如SSH。

ChannelPipeLine接口

public interface ChannelPipeline extends ChannelInboundInvoker, ChannelOutboundInvoker {

MessageBuf<Object> inboundMessageBuffer();

ByteBuf inboundByteBuffer();

MessageBuf<Object> outboundMessageBuffer();

ByteBuf outboundByteBuffer();

ChannelPipeline addFirst(String name, ChannelHandler handler);

ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);

ChannelPipeline addLast(String name, ChannelHandler handler);

ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);

ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);

ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);

ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);

ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);

ChannelPipeline addFirst(ChannelHandler handlers);

ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler handlers);

ChannelPipeline addLast(ChannelHandler handlers);

ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler handlers);

void remove(ChannelHandler handler);

ChannelHandler remove(String name);

<T extends ChannelHandler> T remove(Class<T> handlerType);

ChannelHandler removeFirst();

ChannelHandler removeLast();

void replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);

ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);

<T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName, ChannelHandler newHandler);

ChannelHandler first();

ChannelHandlerContext firstContext();

ChannelHandler last();

ChannelHandlerContext lastContext();

ChannelHandler get(String name);

<T extends ChannelHandler> T get(Class<T> handlerType);

ChannelHandlerContext context(ChannelHandler handler);

ChannelHandlerContext context(String name);

ChannelHandlerContext context(Class<? extends ChannelHandler> handlerType);

Channel channel();

List<String> names();

Map<String, ChannelHandler> toMap();

}

ChannelPipeline类UML图.JPG

ChannelPipeline类UML图
ChannelHandler接口用于处理和拦截Channel接口中的ChannelEvents。Netty中的ChannelPipeline概念使用了Intecepting Filter Patter模式来实现,这样做的好处是允许用户可以完全控制Event的处理,并且控制ChannelHandlers在ChannelPipeline的交互。

当一个全新的Channel创建的时候,都必须创建一个ChannelPipeline,并使Channel和ChannelPipeline想关联。这种关联关系式永久性的,这意味着,一旦一个ChannelPipeleine和Channel关联了,那么这个Channel就在也无法关联其他ChannelPipeline,也无法取消与当前ChannelPipeline的关联。

【官方推荐】使用Channel接口中的pipeleine()方法来创建一个ChannelPipelien,而不要用new去实例一个ChannePipeline类
ChannelPipeline pipeline = Channel.pipeline();

Pipeline中的事件流

ChannelPipeline中的事件流.JPG

图中显示了一个典型的ChannelHandler或者ChannelPipeline对于ChannelEvent的处理流程。ChannelHandler接口有两个子类,分别是ChannelUpstreamHandler(ChannelInboundHandler)和ChannelDownstreamHandler(ChannelOutBoundstreamHandler)。这两个之类用于处理每一个ChannelEvent,然后由ChannelHandlerContext.sendUpstream(ChannelEvent)和ChannelHandlerContext.sendDownstream(ChannelEvent)将每一个ChannelEvent转发到最近的handler。根据upstream和downstream的不同,每个Event的处理也会有所不同。

如事件流图中的左边显示,Upstream Handlers会从低至上的处理一个Upstream Event。Inbound的数据有图中底部的Netty Internal I/O threads生成。通过调用InputStream.readByte(byte[])方法,可以从一个远程的服务器读取inbound data。如果一个upstream event达到upstream handler的顶部,那么这个upstream event最终将被丢弃掉。

如事件流图中的右边显示,Dpstream Handlers会从低至上的处理一个Upstream Event。Downstream Handler会生成和传输outbount数据流,比如一个写操作。当一个Downstream Event达到Downstream Handler的底部,那么与之相关的Channal中的I/O thread对对其进行处理。Channel中的I/Othread会执行真正的操作,例如OutputStream.write(byte[])。

假设我们创建了这么一个ChannelPipeline,
ChannelPipelien p = Channel.pipeline();
p.addLast(“1”, new UpstreamHandlerA());
p.addList(“2”, new UpstreamHandlerB());
p.addList(“3”, new DownstreamHandlerA());
p.addList(“4”, new DownstreamHandlerB());
p.addList(“5”, new UpstreamHandlerX());
在ChannelPipeline的栈中,upstream的执行顺序是1,2,而downstream的执行顺序是4,3。

生产Pipeline

在一条Pipeline中,一般会有一个或者多个ChannelHandler用于接收I/O事件(read)或者请求I/O操作(write,close)。一个典型的服务器会有如下的一个ChannelPipeline用于处理不同的ChannelHandler。
ChannelPipelien p = Channel.pipeline();
p.addLast(“decoder”, new MyProtocalDecoder());
p.addList(“encoder”, new MyProtocalEncoder());
p.addList(“executor”, new ExectionHandler());
p.addList(“handler”, new MyBusinessLogicHandler());

1.   Protocal Decoder – 将二进制数据(如ByteBuf)装换成Java对象。
2.   Protocal Encoder – 将Java对象装换成二进制数据。
3.   ExecutionHandler – 使用一个线程模型。
4.   BusinessLogicHandler – 执行一个具体的业务逻辑(如数据库访问)

由于ChannelPipeline是线程安全的,所以ChannelHandler可以再任何时候从ChannelPipeline中被添加或者删除。例如,可以插入一个Handler用于处理被加密过的敏感数据信息,在处理之后,删除掉这个Handler。