-
by {@link ServerSocketChannel}, will return the {@link ServerSocketChannel}
-
as its parent on {@link #parent()}.
-
-
The semantics of the hierarchical structure depends on the transport
-
implementation where the {@link Channel} belongs to. For example, you could
-
write a new {@link Channel} implementation that creates the sub-channels that
-
share one socket connection, as BEEP and
-
SSH do.
-
Downcast to access transport-specific operations
-
-
Some transports exposes additional operations that is specific to the
-
transport. Down-cast the {@link Channel} to sub-type to invoke such
-
operations. For example, with the old I/O datagram transport, multicast
-
join / leave operations are provided by {@link DatagramChannel}.
-
Release resources
-
-
It is important to call {@link #close()} or {@link #close(ChannelPromise)} to release all
-
resources once you are done with the {@link Channel}. This ensures all resources are
-
released in a proper way, i.e. filehandles.
*/
-
通道状态主要包括:打开、关闭、连接。
-
通道主要的IO操作,读(read)、写(write)、连接(connect)、绑定(bind)。
-
所有的IO操作都是异步的,调用诸如read,write方法后,并不保证IO操作完成,但会返回一个凭证,在IO操作成功,取消或失败后会记录在该凭证中。
-
channel有父子关系,SocketChannel是通过ServerSocketChannel接受创建的,故SocketChannel的parent()方法返回的就是ServerSocketChannel。
-
在Channel使用完毕后,请调用close方法,释放通道占用的资源。
2、Netty Channel API
===================
接下来重点介绍一下Channel的API。
/**
-
Returns the globally unique identifier of this {@link Channel}.
-
返回全局唯一的channel id
*/
ChannelId id();
/**
-
Return the {@link EventLoop} this {@link Channel} was registered too.
-
返回该Channel注册的线程模型,先理解为Ractor模型的Ractor线程。
*/
EventLoop eventLoop();
/**
-
Returns the parent of this channel.
-
@return the parent channel.
-
{@code null} if this channel does not have a parent channel.
-
返回该Channel由谁创建的,ServerSocketChannel返回null,SocketChannel返回创建它的ServerSocketChannel
*/
Channel parent();
/**
-
Returns the configuration of this channel.
-
返回通道的配置信息
*/
ChannelConfig config();
/**
-
Returns {@code true} if the {@link Channel} is open an may get active later
-
通道是否打开
*/
boolean isOpen();
/**
-
Returns {@code true} if the {@link Channel} is registered with an {@link EventLoop}.
-
该通道是否已经注册在事件模型中,此处先参考Nio编程模型,一个通过需要注册在Register上
*/
boolean isRegistered();
/**
-
Return {@code true} if the {@link Channel} is active and so connected.
-
通道是否激活
*/
boolean isActive();
/**
-
Return the {@link ChannelMetadata} of the {@link Channel} which describe the nature of the {@link Channel}.
-
通道是否支持 调用disconnect方法后,调用connect方法
*/
ChannelMetadata metadata();
/**
-
Returns the local address where this channel is bound to. The returned
-
{@link SocketAddress} is supposed to be down-cast into more concrete
-
type such as {@link InetSocketAddress} to retrieve the detailed
-
information.
-
@return the local address of this channel.
-
{@code null} if this channel is not bound.
-
返回绑定的地址,服务端的Channel返回监听的地址,而客户端的Channel返回连接到服务端的本地套接字。
*/
SocketAddress localAddress();
/**
-
Returns the remote address where this channel is connected to. The
-
returned {@link SocketAddress} is supposed to be down-cast into more
-
concrete type such as {@link InetSocketAddress} to retrieve the detailed
-
information.
-
@return the remote address of this channel.
-
{@code null} if this channel is not connected.
-
If this channel is not connected but it can receive messages
-
from arbitrary remote addresses (e.g. {@link DatagramChannel},
-
use {@link DatagramPacket#recipient()} to determine
-
the origination of the received message as this method will
-
return {@code null}.
-
返回channel的远程套接字。
*/
SocketAddress remoteAddress();
/**
-
Returns the {@link ChannelFuture} which will be notified when this
-
channel is closed. This method always returns the same future instance.
-
通道的关闭凭证(许可),这里是多线程编程一种典型的设计模式,一个channle返回一个固定的
*/
ChannelFuture closeFuture();
/**
-
Returns {@code true} if and only if the I/O thread will perform the
-
requested write operation immediately. Any write requests made when
-
this method returns {@code false} are queued until the I/O thread is
-
ready to process the queued write requests.
-
是否可写,如果通道的写缓冲区未满,即返回true,表示写操作可以立即
-
操作缓冲区,然后返回。
*/
boolean isWritable();
/**
- Returns an internal-use-only object that provides unsafe operations.
*/
Unsafe unsafe();
/**
-
Return the assigned {@link ChannelPipeline}
-
返回管道
*/
ChannelPipeline pipeline();
/**
-
Return the assigned {@link ByteBufAllocator} which will be used to allocate {@link ByteBuf}s.
-
返回ByteBuf内存分配器
*/
ByteBufAllocator alloc();
/**
-
Return a new {@link ChannelPromise}.
-
诸如newPromise,newSuccessedFuture()方法,就是返回一个凭证,用来保存通知结果的,是多线程编程一 * 中典型的设计模式
*/
ChannelPromise newPromise();
/**
- Return an new {@link ChannelProgressivePromise}
*/
ChannelProgressivePromise newProgressivePromise();
/**
-
Create a new {@link ChannelFuture} which is marked as succeeded already. So {@link ChannelFuture#isSuccess()}
-
will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also
-
every call of blocking methods will just return without blocking.
*/
ChannelFuture newSucceededFuture();
/**
-
Create a new {@link ChannelFuture} which is marked as failed already. So {@link ChannelFuture#isSuccess()}
-
will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also
-
every call of blocking methods will just return without blocking.
*/
ChannelFuture newFailedFuture(Throwable cause);
/**
-
Return a special ChannelPromise which can be reused for different operations.
-
-
It’s only supported to use
-
it for {@link Channel#write(Object, ChannelPromise)}.
-
-
Be aware that the returned {@link ChannelPromise} will not support most operations and should only be used
-
if you want to save an object allocation for every write operation. You will not be able to detect if the
-
operation was complete, only if it failed as the implementation will call
-
{@link ChannelPipeline#fireExceptionCaught(Throwable)} in this case.
-
Be aware this is an expert feature and should be used with care!
*/
ChannelPromise voidPromise();
/**
-
Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
-
completes, either because the operation was successful or because of an error.
-
-
This will result in having the
-
{@link ChannelHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
-
called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
-
绑定
*/
ChannelFuture bind(SocketAddress localAddress);
/**
-
Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
-
completes, either because the operation was successful or because of an error.
-
-
If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with
-
a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException}
-
will be used.
-
-
This will result in having the
-
{@link ChannelHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
-
method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
-
连接
*/
ChannelFuture connect(SocketAddress remoteAddress);
/**
-
Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the
-
{@link ChannelFuture} once the operation completes, either because the operation was successful or because of
-
an error.
-
-
This will result in having the
-
{@link ChannelHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
-
method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
*/
ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress);
/**
-
Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes,
-
either because the operation was successful or because of an error.
-
-
This will result in having the
-
{@link ChannelHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
-
method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
-
断开连接
*/
ChannelFuture disconnect();
/**
-
Request to close this {@link Channel} and notify the {@link ChannelFuture} once the operation completes,
-
either because the operation was successful or because of
-
an error.
-
After it is closed it is not possible to reuse it again.
-
-
This will result in having the
-
{@link ChannelHandler#close(ChannelHandlerContext, ChannelPromise)}
-
method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
-
关闭,释放通道资源
*/
ChannelFuture close();
/**
-
Request to deregister this {@link Channel} from its assigned {@link EventLoop} and notify the
-
{@link ChannelFuture} once the operation completes, either because the operation was successful or because of
-
an error.
-
-
This will result in having the
-
{@link ChannelHandler#deregister(ChannelHandlerContext, ChannelPromise)}
-
method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
-
-
After this method completes (not the {@link ChannelFuture}!) one can not submit new tasks to the
-
{@link Channel}'s {@link EventLoop} until the {@link Channel} is again registered with an {@link EventLoop}.
-
Any attempt to do so will result in a {@link RejectedExecutionException} being thrown.
-
Any tasks that were submitted before the call to {@link #deregister()} will finish before the
-
{@link ChannelFuture} completes. Furthermore, periodic and delayed tasks will not be executed until the
-
{@link Channel} is registered with an {@link EventLoop} again. Theses are tasks submitted
-
to the {@link EventLoop} via one of the methods declared
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
by {@link ScheduledExecutorService}.
-
Please note that all of the above only applies to tasks created from within the deregistered {@link Channel}'s
-
{@link ChannelHandler}s.
-
-
It’s only safe to {@linkplain EventLoop#register(Channel)} the {@link Channel} with another (or the same)
-
{@link EventLoop} after the {@link ChannelFuture} has completed.
*/
ChannelFuture deregister();
/**
-
Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
-
completes, either because the operation was successful or because of an error.
-
The given {@link ChannelPromise} will be notified.
-
-
This will result in having the
-
{@link ChannelHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
-
called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
*/
ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise);
/**
-
Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
-
completes, either because the operation was successful or because of an error.
-
The given {@link ChannelFuture} will be notified.
-
-
If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with
-
a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException}
-
will be used.
-
-
This will result in having the
-
{@link ChannelHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
-
method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
*/
ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise);
/**
-
Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the
-
{@link ChannelFuture} once the operation completes, either because the operation was successful or because of
-
an error.
-
The given {@link ChannelPromise} will be notified and also returned.
-
-
This will result in having the
-
{@link ChannelHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
-
method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
*/
ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);
/**
-
Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes,
-
either because the operation was successful or because of an error.
-
The given {@link ChannelPromise} will be notified.
-
-
This will result in having the
-
{@link ChannelHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
-
method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
*/
ChannelFuture disconnect(ChannelPromise promise);
/**
-
Request to close this {@link Channel} and notify the {@link ChannelFuture} once the operation completes,
-
either because the operation was successful or because of
-
an error.
-
After it is closed it is not possible to reuse it again.
-
The given {@link ChannelPromise} will be notified.
-
-
This will result in having the
-
{@link ChannelHandler#close(ChannelHandlerContext, ChannelPromise)}
-
method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
*/
ChannelFuture close(ChannelPromise promise);
/**
-
Request to deregister this {@link Channel} from its assigned {@link EventLoop} and notify the
-
{@link ChannelPromise} once the operation completes, either because the operation was successful or because of
-
an error.
-
-
This will result in having the
-
{@link ChannelHandler#deregister(ChannelHandlerContext, ChannelPromise)}
-
method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
-
-
After this method completes (not the {@link ChannelPromise}!) one can not submit new tasks to the
-
{@link Channel}'s {@link EventLoop} until the {@link Channel} is again registered with an {@link EventLoop}.
-
Any attempt to do so will result in a {@link RejectedExecutionException} being thrown.
-
Any tasks that were submitted before the call to {@link #deregister()} will finish before the
-
{@link ChannelPromise} completes. Furthermore, periodic and delayed tasks will not be executed until the
-
{@link Channel} is registered with an {@link EventLoop} again. Theses are tasks submitted
-
to the {@link EventLoop} via one of the methods declared by {@link ScheduledExecutorService}.
-
Please note that all of the above only applies to tasks created from within the deregistered {@link Channel}'s
-
{@link ChannelHandler}s.
-
-
It’s only safe to {@linkplain EventLoop#register(Channel)} the {@link Channel} with another (or the same)
-
{@link EventLoop} after the {@link ChannelPromise} has completed.
*/
ChannelFuture deregister(ChannelPromise promise);
/**
-
Request to Read data from the {@link Channel} into the first inbound buffer, triggers an
-
{@link ChannelHandler#channelRead(ChannelHandlerContext, Object)} event if data was
-
read, and triggers a
-
{@link ChannelHandler#channelReadComplete(ChannelHandlerContext) channelReadComplete} event so the
-
handler can decide to continue reading. If there’s a pending read operation already, this method does nothing.
-
-
This will result in having the
-
{@link ChannelHandler#read(ChannelHandlerContext)}
-
method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
-
{@link Channel}.
*/
Channel read();
/**
-
Request to write a message via this {@link Channel} through the {@link ChannelPipeline}.
-
This method will not request to actual flush, so be sure to call {@link #flush()}
-
once you want to request to flush all pending data to the actual transport.
*/
ChannelFuture write(Object msg);
/**
-
Request to write a message via this {@link Channel} through the {@link ChannelPipeline}.
-
This method will not request to actual flush, so be sure to call {@link #flush()}
-
once you want to request to flush all pending data to the actual transport.
*/
ChannelFuture write(Object msg, ChannelPromise promise);
/**
- Request to flush all pending messages.
*/
Channel flush();
/**
- Shortcut for call {@link #write(Object, ChannelPromise)} and {@link #flush()}.
*/
ChannelFuture writeAndFlush(Object msg, ChannelPromise promise);
/**
- Shortcut for call {@link #write(Object)} and {@link #flush()}.
*/
ChannelFuture writeAndFlush(Object msg);