Netty学习之旅------Netty Channel 概述,java面试没有项目经验

本文详细介绍了Netty Channel的相关概念和API,包括Channel的状态、IO操作、父子关系,以及各种方法如bind、connect、close等的用途。通过理解这些内容,可以帮助开发者更好地掌握Netty框架在后端开发中的应用。
摘要由CSDN通过智能技术生成
  • 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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值