This is a helper class that makes it easy to bootstrap an <seecref="T:DotNetty.Transport.Channels.IChannel"/>. It supports method-
chaining to provide an easy way to configure the <seecref="T:DotNetty.Transport.Bootstrapping.AbstractBootstrap`2"/>.
When not used in a <seecref="T:DotNetty.Transport.Bootstrapping.ServerBootstrap"/> context, the <seecref="M:DotNetty.Transport.Bootstrapping.AbstractBootstrap`2.BindAsync(System.Net.EndPoint)"/> methods
are useful for connectionless transports such as datagram (UDP).
Specifies the <seecref="T:DotNetty.Transport.Channels.IEventLoopGroup"/> which will handle events for the <seecref="T:DotNetty.Transport.Channels.IChannel"/> being built.
</summary>
<paramname="group">The <seecref="T:DotNetty.Transport.Channels.IEventLoopGroup"/> which is used to handle all the events for the to-be-created <seecref="T:DotNetty.Transport.Channels.IChannel"/>.</param>
Specifies the <seecref="T:System.Type"/> of <seecref="T:DotNetty.Transport.Channels.IChannel"/> which will be created.
</summary>
<typeparamname="T">The <seecref="T:System.Type"/> which is used to create <seecref="T:DotNetty.Transport.Channels.IChannel"/> instances from.</typeparam>
Creates a new <seecref="T:DotNetty.Transport.Channels.IChannel"/> and binds it to the endpoint specified via the <seecref="M:DotNetty.Transport.Bootstrapping.AbstractBootstrap`2.LocalAddress(System.Net.EndPoint)"/> methods.
A <seecref="T:DotNetty.Transport.Bootstrapping.Bootstrap"/> that makes it easy to bootstrap an <seecref="T:DotNetty.Transport.Channels.IChannel"/> to use for clients.
The <seecref="M:DotNetty.Transport.Bootstrapping.AbstractBootstrap`2.BindAsync(System.Net.EndPoint)"/> methods are useful
in combination with connectionless transports such as datagram (UDP). For regular TCP connections,
please use the provided <seecref="M:DotNetty.Transport.Bootstrapping.Bootstrap.ConnectAsync(System.Net.EndPoint,System.Net.EndPoint)"/> methods.
Sets the <seecref="T:DotNetty.Transport.Bootstrapping.INameResolver"/> which will resolve the address of the unresolved named address.
</summary>
<paramname="resolver">The <seecref="T:DotNetty.Transport.Bootstrapping.INameResolver"/> which will resolve the address of the unresolved named address.</param>
Assigns the remote <seecref="T:System.Net.EndPoint"/> to connect to once the <seecref="M:DotNetty.Transport.Bootstrapping.Bootstrap.ConnectAsync"/> method is called.
</summary>
<paramname="remoteAddress">The remote <seecref="T:System.Net.EndPoint"/> to connect to.</param>
Assigns the remote <seecref="T:System.Net.EndPoint"/> to connect to once the <seecref="M:DotNetty.Transport.Bootstrapping.Bootstrap.ConnectAsync"/> method is called.
</summary>
<paramname="inetHost">The hostname of the endpoint to connect to.</param>
<paramname="inetPort">The port at the remote host to connect to.</param>
Assigns the remote <seecref="T:System.Net.EndPoint"/> to connect to once the <seecref="M:DotNetty.Transport.Bootstrapping.Bootstrap.ConnectAsync"/> method is called.
</summary>
<paramname="inetHost">The <seecref="T:System.Net.IPAddress"/> of the endpoint to connect to.</param>
<paramname="inetPort">The port at the remote host to connect to.</param>
Returns a deep clone of this bootstrap which has the identical configuration except that it uses
the given <seecref="T:DotNetty.Transport.Channels.IEventLoopGroup"/>. This method is useful when making multiple <seecref="T:DotNetty.Transport.Channels.IChannel"/>s with similar
A <seecref="T:DotNetty.Transport.Bootstrapping.Bootstrap"/> sub-class which allows easy bootstrapping of <seecref="T:DotNetty.Transport.Channels.IServerChannel"/>.
Sets the <seecref="T:DotNetty.Transport.Channels.IEventLoopGroup"/> for the parent (acceptor) and the child (client). These
<seecref="T:DotNetty.Transport.Channels.IEventLoopGroup"/>'s are used to handle all the events and IO for <seecref="T:DotNetty.Transport.Channels.IServerChannel"/>
and <seecref="T:DotNetty.Transport.Channels.IChannel"/>'s.
Allows specification of a <seecref="T:DotNetty.Transport.Channels.ChannelOption"/> which is used for the <seecref="T:DotNetty.Transport.Channels.IChannel"/>
instances once they get created (after the acceptor accepted the <seecref="T:DotNetty.Transport.Channels.IChannel"/>). Use a
value of <c>null</c> to remove a previously set <seecref="T:DotNetty.Transport.Channels.ChannelOption"/>.
Sets the specific <seecref="T:DotNetty.Common.Utilities.AttributeKey`1"/> with the given value on every child <seecref="T:DotNetty.Transport.Channels.IChannel"/>.
If the value is <c>null</c>, the <seecref="T:DotNetty.Common.Utilities.AttributeKey`1"/> is removed.
Sets the <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> which is used to serve the request for the <seecref="T:DotNetty.Transport.Channels.IChannel"/>'s.
Returns a new <seecref="T:DotNetty.Transport.Channels.DefaultChannelId"/> instance. Subclasses may override this method to assign custom
<seecref="T:DotNetty.Transport.Channels.IChannelId"/>s to <seecref="T:DotNetty.Transport.Channels.IChannel"/>s that use the <seecref="T:DotNetty.Transport.Channels.AbstractChannel"/> constructor.
</summary>
<returns>A new <seecref="T:DotNetty.Transport.Channels.DefaultChannelId"/> instance.</returns>
Returns the string representation of this channel. The returned string contains a hex dump of the
<seecref="T:DotNetty.Transport.Channels.IChannelId"/>, the <seecref="P:DotNetty.Transport.Channels.AbstractChannel.LocalAddress"/>, and the <seecref="P:DotNetty.Transport.Channels.AbstractChannel.RemoteAddress"/> of this
Prepares to close the <seecref="T:DotNetty.Transport.Channels.IChannel"/>. If this method returns an <seecref="T:DotNetty.Common.Concurrency.IEventExecutor"/>, the
caller must call the <seecref="!:IEventExecutor.Execute(DotNetty.Common.Concurrency.IRunnable)"/> method with a task that calls
<seecref="M:DotNetty.Transport.Channels.AbstractChannel.DoClose"/> on the returned <seecref="T:DotNetty.Common.Concurrency.IEventExecutor"/>. If this method returns <c>null</c>,
<seecref="M:DotNetty.Transport.Channels.AbstractChannel.DoClose"/> must be called from the caller thread. (i.e. <seecref="T:DotNetty.Transport.Channels.IEventLoop"/>)
Checks whether a given <seecref="T:DotNetty.Transport.Channels.IEventLoop"/> is compatible with the <seecref="T:DotNetty.Transport.Channels.AbstractChannel"/>.
</summary>
<paramname="eventLoop">The <seecref="T:DotNetty.Transport.Channels.IEventLoop"/> to check compatibility.</param>
<returns>
<c>true</c> if the given <seecref="T:DotNetty.Transport.Channels.IEventLoop"/> is compatible with this <seecref="T:DotNetty.Transport.Channels.AbstractChannel"/>
Is called after the <seecref="T:DotNetty.Transport.Channels.IChannel"/> is registered with its <seecref="T:DotNetty.Transport.Channels.IEventLoop"/> as part of the
register process. Sub-classes may override this method.
Deregisters the <seecref="T:DotNetty.Transport.Channels.IChannel"/> from its <seecref="T:DotNetty.Transport.Channels.IEventLoop"/>. Sub-classes may override this
Invoked when a new message is added to a <seecref="T:DotNetty.Transport.Channels.ChannelOutboundBuffer"/> of this
<seecref="T:DotNetty.Transport.Channels.AbstractChannel"/>, so that the <seecref="T:DotNetty.Transport.Channels.IChannel"/> implementation converts the message to
another. (e.g. heap buffer -> direct buffer).
</summary>
<paramname="msg">The message to be filtered.</param>
<summary>Neither <seecref="M:DotNetty.Transport.Channels.IChannelHandler.HandlerAdded(DotNetty.Transport.Channels.IChannelHandlerContext)"/> nor <seecref="M:DotNetty.Transport.Channels.IChannelHandler.HandlerRemoved(DotNetty.Transport.Channels.IChannelHandlerContext)"/> was called.</summary>
<summary><seecref="M:DotNetty.Transport.Channels.IChannelHandler.HandlerAdded(DotNetty.Transport.Channels.IChannelHandlerContext)"/> was called.</summary>
<summary><seecref="M:DotNetty.Transport.Channels.IChannelHandler.HandlerRemoved(DotNetty.Transport.Channels.IChannelHandlerContext)"/> was called.</summary>
Makes best possible effort to detect if <seecref="M:DotNetty.Transport.Channels.IChannelHandler.HandlerAdded(DotNetty.Transport.Channels.IChannelHandlerContext)"/> was
called
yet. If not return <c>false</c> and if called or could not detect return <c>true</c>.
If this method returns <c>true</c> we will not invoke the <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> but just forward the
event.
This is needed as <seecref="T:DotNetty.Transport.Channels.DefaultChannelPipeline"/> may already put the <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> in the
A skeletal server-side <seecref="T:DotNetty.Transport.Channels.IChannel"/> implementation. A server-side <seecref="T:DotNetty.Transport.Channels.IChannel"/> does not
allow the following operations: <seecref="M:DotNetty.Transport.Channels.IChannel.ConnectAsync(System.Net.EndPoint)"/>,
<seecref="T:DotNetty.Transport.Channels.IEventLoopGroup"/> that works as a wrapper for another <seecref="T:DotNetty.Transport.Channels.IEventLoopGroup"/> providing affinity on <seecref="M:DotNetty.Transport.Channels.AffinitizedEventLoopGroup.GetNext"/> call.
Creates a new instance of <seecref="T:DotNetty.Transport.Channels.AffinitizedEventLoopGroup"/>.
</summary>
<paramname="innerGroup"><seecref="T:DotNetty.Transport.Channels.IEventLoopGroup"/> serving as an actual provider of <seecref="T:DotNetty.Transport.Channels.IEventLoop"/>s.</param>
If running in a context of an existing <seecref="T:DotNetty.Transport.Channels.IEventLoop"/>, this <seecref="T:DotNetty.Transport.Channels.IEventLoop"/> is returned.
Otherwise, <seecref="T:DotNetty.Transport.Channels.IEventLoop"/> is retrieved from underlying <seecref="T:DotNetty.Transport.Channels.IEventLoopGroup"/>.
A queue of write operations which are pending for later execution. It also updates the
<seecref="P:DotNetty.Transport.Channels.IChannel.IsWritable">writability</see> of the associated <seecref="T:DotNetty.Transport.Channels.IChannel"/>, so that
the pending write operations are also considered to determine the writability.
<seecref="T:System.Threading.Tasks.Task"/> if something was written and <c>null</c> if the <seecref="T:DotNetty.Transport.Channels.BatchingPendingWriteQueue"/>
<seecref="T:System.Threading.Tasks.Task"/> if something was written and <c>null</c> if the <seecref="T:DotNetty.Transport.Channels.BatchingPendingWriteQueue"/>
A special <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> which offers an easy way to initialize a <seecref="T:DotNetty.Transport.Channels.IChannel"/> once it was
registered to its <seecref="T:DotNetty.Transport.Channels.IEventLoop"/>.
<para>
Implementations are most often used in the context of <seecref="M:DotNetty.Transport.Bootstrapping.AbstractBootstrap`2.Handler(DotNetty.Transport.Channels.IChannelHandler)"/>
and <seecref="M:DotNetty.Transport.Bootstrapping.ServerBootstrap.ChildHandler(DotNetty.Transport.Channels.IChannelHandler)"/> to setup the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of a <seecref="T:DotNetty.Transport.Channels.IChannel"/>.
</para>
Be aware that this class is marked as Sharable (via <seecref="P:DotNetty.Transport.Channels.ChannelInitializer`1.IsSharable"/>) and so the implementation must be safe to be re-used.
</summary>
<example>
<code>
public class MyChannelInitializer extends <seecref="T:DotNetty.Transport.Channels.ChannelInitializer`1"/> {
public void InitChannel(<seecref="T:DotNetty.Transport.Channels.IChannel"/> channel) {
channel.Pipeline().AddLast("myHandler", new MyHandler());
Checks whether a given <seecref="T:DotNetty.Transport.Channels.ChannelOption"/> exists.
</summary>
<paramname="name">The name of the <seecref="T:DotNetty.Transport.Channels.ChannelOption"/>.</param>
<returns><c>true</c> if a <seecref="T:DotNetty.Transport.Channels.ChannelOption"/> exists for the given <paramrefname="name"/>, otherwise <c>false</c>.</returns>
Creates a new <seecref="T:DotNetty.Transport.Channels.ChannelOption"/> for the given <paramrefname="name"/>.
</summary>
<typeparamname="T">The type of option to create.</typeparam>
<paramname="name">The name to associate with the new option.</param>
<exceptioncref="T:System.ArgumentException">Thrown if a <seecref="T:DotNetty.Transport.Channels.ChannelOption"/> for the given <paramrefname="name"/> exists.</exception>
<returns>The new <seecref="T:DotNetty.Transport.Channels.ChannelOption`1"/> instance.</returns>
Returns a list of direct ArraySegment<byte>, if the currently pending messages are made of
<seecref="T:DotNetty.Buffers.IByteBuffer"/> instances only. <seecref="P:DotNetty.Transport.Channels.ChannelOutboundBuffer.NioBufferSize"/> will return the total number of
readable bytes of these buffers.
<para>
Note that the returned array is reused and thus should not escape
<seecref="M:DotNetty.Transport.Channels.AbstractChannel.DoWrite(DotNetty.Transport.Channels.ChannelOutboundBuffer)"/>. Refer to
<seecref="M:DotNetty.Transport.Channels.Sockets.TcpSocketChannel.DoWrite(DotNetty.Transport.Channels.ChannelOutboundBuffer)"/> for an example.
</para>
</summary>
<returns>A list of ArraySegment<byte> buffers.</returns>
Returns a list of direct ArraySegment<byte>, if the currently pending messages are made of
<seecref="T:DotNetty.Buffers.IByteBuffer"/> instances only. <seecref="P:DotNetty.Transport.Channels.ChannelOutboundBuffer.NioBufferSize"/> will return the total number of
readable bytes of these buffers.
<para>
Note that the returned array is reused and thus should not escape
<seecref="M:DotNetty.Transport.Channels.AbstractChannel.DoWrite(DotNetty.Transport.Channels.ChannelOutboundBuffer)"/>. Refer to
<seecref="M:DotNetty.Transport.Channels.Sockets.TcpSocketChannel.DoWrite(DotNetty.Transport.Channels.ChannelOutboundBuffer)"/> for an example.
</para>
</summary>
<paramname="maxCount">The maximum amount of buffers that will be added to the return value.</param>
<paramname="maxBytes">A hint toward the maximum number of bytes to include as part of the return value. Note that this value maybe exceeded because we make a best effort to include at least 1 <seecref="T:DotNetty.Buffers.IByteBuffer"/> in the return value to ensure write progress is made.</param>
<returns>A list of ArraySegment<byte> buffers.</returns>
Returns <c>true</c> if and only if the total number of pending bytes (<seecref="M:DotNetty.Transport.Channels.ChannelOutboundBuffer.TotalPendingWriteBytes"/>)
did not exceed the write watermark of the <seecref="T:DotNetty.Transport.Channels.IChannel"/> and no user-defined writability flag
(<seecref="M:DotNetty.Transport.Channels.ChannelOutboundBuffer.SetUserDefinedWritability(System.Int32,System.Boolean)"/>) has been set to <c>false</c>.
Gets the number of bytes that can be written before <seecref="P:DotNetty.Transport.Channels.ChannelOutboundBuffer.IsWritable"/> returns <c>false</c>.
This quantity will always be non-negative. If <seecref="P:DotNetty.Transport.Channels.ChannelOutboundBuffer.IsWritable"/> is already <c>false</c>, then 0 is
returned.
</summary>
<returns>
The number of bytes that can be written before <seecref="P:DotNetty.Transport.Channels.ChannelOutboundBuffer.IsWritable"/> returns <c>false</c>.
Gets the number of bytes that must be drained from the underlying buffer before <seecref="P:DotNetty.Transport.Channels.ChannelOutboundBuffer.IsWritable"/>
returns <c>true</c>. This quantity will always be non-negative. If <seecref="P:DotNetty.Transport.Channels.ChannelOutboundBuffer.IsWritable"/> is already
<c>true</c>, then 0 is returned.
</summary>
<returns>
The number of bytes that can be written before <seecref="P:DotNetty.Transport.Channels.ChannelOutboundBuffer.IsWritable"/> returns <c>true</c>.
Calls <seecref="M:DotNetty.Transport.Channels.ChannelOutboundBuffer.IMessageProcessor.ProcessMessage(System.Object)"/> for each flushed message in this
<seecref="T:DotNetty.Transport.Channels.ChannelOutboundBuffer"/> until <seecref="M:DotNetty.Transport.Channels.ChannelOutboundBuffer.IMessageProcessor.ProcessMessage(System.Object)"/> returns
<c>false</c> or there are no more flushed messages to process.
</summary>
<paramname="processor">
The <seecref="T:DotNetty.Transport.Channels.ChannelOutboundBuffer.IMessageProcessor"/> intance to use to process each flushed message.
This is the head of a linked list that is processed by <seecref="M:DotNetty.Transport.Channels.DefaultChannelPipeline.CallHandlerAddedForAllHandlers"/> and so
process all the pending <seecref="M:DotNetty.Transport.Channels.DefaultChannelPipeline.CallHandlerAdded0(DotNetty.Transport.Channels.AbstractChannelHandlerContext)"/>. We only keep the head because it is expected that
the list is used infrequently and its size is small. Thus full iterations to do insertions is assumed to be
a good compromised to saving memory and tail management complexity.
Removes all handlers from the pipeline one by one from tail (exclusive) to head (exclusive) to trigger
<seecref="M:DotNetty.Transport.Channels.IChannelHandler.HandlerRemoved(DotNetty.Transport.Channels.IChannelHandlerContext)"/>. Note that we traverse up the pipeline <seecref="M:DotNetty.Transport.Channels.DefaultChannelPipeline.DestroyUp(DotNetty.Transport.Channels.AbstractChannelHandlerContext,System.Boolean)"/>
before traversing down <seecref="M:DotNetty.Transport.Channels.DefaultChannelPipeline.DestroyDown(System.Threading.Thread,DotNetty.Transport.Channels.AbstractChannelHandlerContext,System.Boolean)"/> so that the handlers are removed after all events are
Called once an <seecref="T:System.Exception"/> hits the end of the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> without being
handled by the user in <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ExceptionCaught(DotNetty.Transport.Channels.IChannelHandlerContext,System.Exception)"/>.
Called once a message hits the end of the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> without being handled by the user
in <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ChannelRead(DotNetty.Transport.Channels.IChannelHandlerContext,System.Object)"/>. This method is responsible
for calling <seecref="M:DotNetty.Common.Utilities.ReferenceCountUtil.Release(System.Object)"/> on the given msg at some point.
<summary>Focuses on enforcing the maximum messages per read condition for <seecref="M:DotNetty.Transport.Channels.DefaultMaxMessagesRecvByteBufAllocator.MaxMessageHandle`1.ContinueReading"/>.</summary>
<summary>Create a new instance with the pipeline initialized with the specified handlers.</summary>
<paramname="id">The <seecref="T:DotNetty.Transport.Channels.IChannelId"/> of this channel.</param>
<paramname="hasDisconnect">
<c>false</c> if this <seecref="T:DotNetty.Transport.Channels.IChannel"/> will delegate <seecref="M:DotNetty.Transport.Channels.Embedded.EmbeddedChannel.DisconnectAsync"/>
to <seecref="M:DotNetty.Transport.Channels.Embedded.EmbeddedChannel.CloseAsync"/>, <c>true</c> otherwise.
</param>
<paramname="handlers">
The <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/>s that will be added to the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/>
Run all pending scheduled tasks in the <seecref="T:DotNetty.Transport.Channels.IEventLoop"/> for this <seecref="T:DotNetty.Transport.Channels.IChannel"/>.
</summary>
<returns>
The <seecref="T:DotNetty.Common.PreciseTimeSpan"/> when the next scheduled task is ready to run. If no other task is
scheduled then it will return <seecref="F:DotNetty.Common.PreciseTimeSpan.Zero"/>.
<summary>Create a new instance with the pipeline initialized with the specified handlers.</summary>
<paramname="id">The <seecref="T:DotNetty.Transport.Channels.IChannelId"/> of this channel.</param>
<paramname="hasDisconnect">
<c>false</c> if this <seecref="T:DotNetty.Transport.Channels.IChannel"/> will delegate <seecref="M:DotNetty.Transport.Channels.Embedded.SingleThreadedEmbeddedChannel.DisconnectAsync"/>
to <seecref="M:DotNetty.Transport.Channels.Embedded.SingleThreadedEmbeddedChannel.CloseAsync"/>, <c>true</c> otherwise.
</param>
<paramname="handlers">
The <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/>s that will be added to the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/>
Return the <seecref="T:DotNetty.Transport.Channels.ChannelMetadata"/> of the <seecref="T:DotNetty.Transport.Channels.IChannel"/> which describe the nature of the
The <seecref="T:DotNetty.Transport.Channels.IChannel"/> of the <seecref="T:DotNetty.Transport.Channels.IChannelHandlerContext"/> was registered with its
The <seecref="T:DotNetty.Transport.Channels.IChannel"/> of the <seecref="T:DotNetty.Transport.Channels.IChannelHandlerContext"/> was unregistered from its
The unique name of the <seecref="T:DotNetty.Transport.Channels.IChannelHandlerContext"/>.
</summary>
<remarks>
The name was used when the <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> was added to the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/>.
This name can also be used to access the registered <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> from the
A <seecref="T:DotNetty.Transport.Channels.IChannel"/> was registered to its <seecref="T:DotNetty.Transport.Channels.IEventLoop"/>. This will result in having the
<seecref="M:DotNetty.Transport.Channels.IChannelHandler.ChannelRegistered(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method called of the next <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/>
contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the <seecref="T:DotNetty.Transport.Channels.IChannel"/>.
</summary>
<returns>The current <seecref="T:DotNetty.Transport.Channels.IChannelHandlerContext"/>.</returns>
A <seecref="T:DotNetty.Transport.Channels.IChannel"/> was unregistered from its <seecref="T:DotNetty.Transport.Channels.IEventLoop"/>. This will result in having the
<seecref="M:DotNetty.Transport.Channels.IChannelHandler.ChannelUnregistered(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method called of the next <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/>
contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the <seecref="T:DotNetty.Transport.Channels.IChannel"/>.
</summary>
<returns>The current <seecref="T:DotNetty.Transport.Channels.IChannelHandlerContext"/>.</returns>
Request to bind to the given <seecref="T:System.Net.EndPoint"/>.
<para>
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.BindAsync(DotNetty.Transport.Channels.IChannelHandlerContext,System.Net.EndPoint)"/> method called of the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
Request to connect to the given <seecref="T:System.Net.EndPoint"/>.
<para>
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ConnectAsync(DotNetty.Transport.Channels.IChannelHandlerContext,System.Net.EndPoint,System.Net.EndPoint)"/> method called of the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
Request to connect to the given <seecref="T:System.Net.EndPoint"/> while also binding to the localAddress.
<para>
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ConnectAsync(DotNetty.Transport.Channels.IChannelHandlerContext,System.Net.EndPoint,System.Net.EndPoint)"/> method called of the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.DisconnectAsync(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method called of the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
Request to deregister from the previous assigned <seecref="T:DotNetty.Common.Concurrency.IEventExecutor"/>.
<para>
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.DeregisterAsync(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method called of the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
to give a user full control over how an event is handled and how the <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/>s in a
pipeline interact with each other.
<para>Creation of a pipeline</para>
<para>Each channel has its own pipeline and it is created automatically when a new channel is created.</para>
<para>How an event flows in a pipeline</para>
<para>
The following diagram describes how I/O events are processed by <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/>s in a
<seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> typically. An I/O event is handled by a <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> and is
forwarded by the <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> which handled the event to the <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/>
which is placed right next to it. A <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> can also trigger an arbitrary I/O event if
necessary. To forward or trigger an event, a <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> calls the event propagation methods
defined in <seecref="T:DotNetty.Transport.Channels.IChannelHandlerContext"/>, such as <seecref="M:DotNetty.Transport.Channels.IChannelHandlerContext.FireChannelRead(System.Object)"/>
and <seecref="M:DotNetty.Transport.Channels.IChannelHandlerContext.WriteAsync(System.Object)"/>.
</para>
<para>
<pre>
I/O Request
via <seecref="T:DotNetty.Transport.Channels.IChannel"/> or
An inbound event is handled by the <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/>s in the bottom-up direction as shown on the
left side of the diagram. An inbound event is usually triggered by the I/O thread on the bottom of the diagram
so that the <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/>s are notified when the state of a <seecref="T:DotNetty.Transport.Channels.IChannel"/> changes
(e.g. newly established connections and closed connections) or the inbound data was read from a remote peer. If
an inbound event goes beyond the <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> at the top of the diagram, it is discarded and
logged, depending on your loglevel.
</para>
<para>
An outbound event is handled by the <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/>s in the top-down direction as shown on the
right side of the diagram. An outbound event is usually triggered by your code that requests an outbound I/O
operation, such as a write request and a connection attempt. If an outbound event goes beyond the
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> at the bottom of the diagram, it is handled by an I/O thread associated with the
<seecref="T:DotNetty.Transport.Channels.IChannel"/>. The I/O thread often performs the actual output operation such as
and the following example shows how the event propagation is usually done:
<code>
public class MyInboundHandler : <seecref="T:DotNetty.Transport.Channels.ChannelHandlerAdapter"/>
{
public override void ChannelActive(<seecref="T:DotNetty.Transport.Channels.IChannelHandlerContext"/> ctx)
{
Console.WriteLine("Connected!");
ctx.FireChannelActive();
}
}
public class MyOutboundHandler : <seecref="T:DotNetty.Transport.Channels.ChannelHandlerAdapter"/>
{
public override async Task CloseAsync(<seecref="T:DotNetty.Transport.Channels.IChannelHandlerContext"/> ctx)
{
Console.WriteLine("Closing...");
await ctx.CloseAsync();
}
}
</code>
</para>
<para>Building a pipeline</para>
<para>
A user is supposed to have one or more <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/>s in a pipeline to receive I/O events
(e.g. read) and to request I/O operations (e.g. write and close). For example, a typical server will have the
following handlers in each channel's pipeline, but your mileage may vary depending on the complexity and
characteristics of the protocol and business logic:
<ol>
<li>Protocol Decoder - translates binary data (e.g. <seecref="T:DotNetty.Buffers.IByteBuffer"/>) into a Java object.</li>
<li>Protocol Encoder - translates a Java object into binary data.</li>
<li>Business Logic Handler - performs the actual business logic (e.g. database access).</li>
</ol>
</para>
<para>
and it could be represented as shown in the following example:
<code>
static readonly <seecref="T:DotNetty.Common.Concurrency.IEventExecutorGroup"/> group = new <seecref="T:DotNetty.Transport.Channels.MultithreadEventLoopGroup"/>();
pipeline.AddLast("decoder", new MyProtocolDecoder());
pipeline.AddLast("encoder", new MyProtocolEncoder());
// Tell the pipeline to run MyBusinessLogicHandler's event handler methods
// in a different thread than an I/O thread so that the I/O thread is not blocked by
// a time-consuming task.
// If your business logic is fully asynchronous or finished very quickly, you don't
// need to specify a group.
pipeline.AddLast(group, "handler", new MyBusinessLogicHandler());
</code>
</para>
<para>Thread safety</para>
<para>
An <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> can be added or removed at any time because an <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/>
is thread safe. For example, you can insert an encryption handler when sensitive information is about to be
An <seecref="T:DotNetty.Transport.Channels.IChannel"/> was registered to its <seecref="T:DotNetty.Transport.Channels.IEventLoop"/>.
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ChannelRegistered(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method
called of the next <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
An <seecref="T:DotNetty.Transport.Channels.IChannel"/> was unregistered from its <seecref="T:DotNetty.Transport.Channels.IEventLoop"/>.
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ChannelUnregistered(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method
called of the next <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
An <seecref="T:DotNetty.Transport.Channels.IChannel"/> is active now, which means it is connected.
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ChannelActive(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method
called of the next <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
An <seecref="T:DotNetty.Transport.Channels.IChannel"/> is inactive now, which means it is closed.
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ChannelInactive(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method
called of the next <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
An <seecref="T:DotNetty.Transport.Channels.IChannel"/> received an <seecref="T:System.Exception"/> in one of its inbound operations.
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ExceptionCaught(DotNetty.Transport.Channels.IChannelHandlerContext,System.Exception)"/> method
called of the next <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
An <seecref="T:DotNetty.Transport.Channels.IChannel"/> received an user defined event.
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.UserEventTriggered(DotNetty.Transport.Channels.IChannelHandlerContext,System.Object)"/> method
called of the next <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
An <seecref="T:DotNetty.Transport.Channels.IChannel"/> received a message.
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ChannelRead(DotNetty.Transport.Channels.IChannelHandlerContext,System.Object)"/> method
called of the next <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
An <seecref="T:DotNetty.Transport.Channels.IChannel"/> completed a message after reading it.
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ChannelReadComplete(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method
called of the next <seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
Triggers an <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ChannelWritabilityChanged(DotNetty.Transport.Channels.IChannelHandlerContext)"/> event to the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/>.
Request to bind to the given <seecref="T:System.Net.EndPoint"/>.
<para>
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.BindAsync(DotNetty.Transport.Channels.IChannelHandlerContext,System.Net.EndPoint)"/> method called of the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
Request to connect to the given <seecref="T:System.Net.EndPoint"/>.
<para>
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ConnectAsync(DotNetty.Transport.Channels.IChannelHandlerContext,System.Net.EndPoint,System.Net.EndPoint)"/> method called of the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
Request to connect to the given <seecref="T:System.Net.EndPoint"/>.
<para>
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.ConnectAsync(DotNetty.Transport.Channels.IChannelHandlerContext,System.Net.EndPoint,System.Net.EndPoint)"/> method called of the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.DisconnectAsync(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method called of the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
Request to close the <seecref="T:DotNetty.Transport.Channels.IChannel"/>. After it is closed it is not possible to reuse it again.
<para>
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.CloseAsync(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method called of the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
Request to deregister the <seecref="T:DotNetty.Transport.Channels.IChannel"/> bound this <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> from the
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.DeregisterAsync(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method called of the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
Request to Read data from the <seecref="T:DotNetty.Transport.Channels.IChannel"/> into the first inbound buffer, triggers an
<seecref="M:DotNetty.Transport.Channels.IChannelHandler.ChannelRead(DotNetty.Transport.Channels.IChannelHandlerContext,System.Object)"/> event if data was read, and triggers a
<seecref="M:DotNetty.Transport.Channels.IChannelHandler.ChannelReadComplete(DotNetty.Transport.Channels.IChannelHandlerContext)"/> event so the handler can decide whether to continue
reading. If there's a pending read operation already, this method does nothing.
<para>
This will result in having the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.Read(DotNetty.Transport.Channels.IChannelHandlerContext)"/> method called of the next
<seecref="T:DotNetty.Transport.Channels.IChannelHandler"/> contained in the <seecref="T:DotNetty.Transport.Channels.IChannelPipeline"/> of the
Shortcut for calling both <seecref="M:DotNetty.Transport.Channels.IChannelPipeline.WriteAsync(System.Object)"/> and <seecref="M:DotNetty.Transport.Channels.IChannelPipeline.Flush"/>.
<seecref="T:DotNetty.Common.Concurrency.IEventExecutor"/> specialized to handle I/O operations of assigned <seecref="T:DotNetty.Transport.Channels.IChannel"/>s.
Similar to <seecref="M:DotNetty.Transport.Channels.IRecvByteBufAllocatorHandle.Allocate(DotNetty.Buffers.IByteBufferAllocator)"/> except that it does not allocate anything but just tells the
Reset any counters that have accumulated and recommend how many messages/bytes should be read for the next
read loop.
<p>
This may be used by <seecref="M:DotNetty.Transport.Channels.IRecvByteBufAllocatorHandle.ContinueReading"/> to determine if the read operation should complete.
</p>
This is only ever a hint and may be ignored by the implementation.
</summary>
<paramname="config">The channel configuration which may impact this object's behavior.</param>
Get or set the bytes that have been read for the last read operation.
This may be used to increment the number of bytes that have been read.
</summary>
<remarks>
Returned value may be negative if an read error
occurs. If a negative value is seen it is expected to be return on the next set to
<seecref="P:DotNetty.Transport.Channels.IRecvByteBufAllocatorHandle.LastBytesRead"/>. A negative value will signal a termination condition enforced externally
to this class and is not required to be enforced in <seecref="M:DotNetty.Transport.Channels.IRecvByteBufAllocatorHandle.ContinueReading"/>.
A <seecref="T:DotNetty.Transport.Channels.IChannel"/> that accepts an incoming connection attempt and creates its child
<seecref="T:DotNetty.Transport.Channels.IChannel"/>s by accepting them. <seecref="T:DotNetty.Transport.Channels.Sockets.IServerSocketChannel"/> is a good example.
A factory method for <seecref="T:DotNetty.Transport.Channels.Local.LocalChannel"/>s. Users may override it to create custom instances of <seecref="T:DotNetty.Transport.Channels.Local.LocalChannel"/>s.
</summary>
<paramname="peer">An existing <seecref="T:DotNetty.Transport.Channels.Local.LocalChannel"/> that will act as a peer for the new channel.</param>
<returns>The newly created <seecref="T:DotNetty.Transport.Channels.Local.LocalChannel"/> instance.</returns>
<seecref="T:DotNetty.Transport.Channels.IEventLoopGroup"/> backed by a set of <seecref="T:DotNetty.Transport.Channels.SingleThreadEventLoop"/> instances.
A queue of write operations which are pending for later execution. It also updates the writability of the
associated <seecref="T:DotNetty.Transport.Channels.IChannel"/> (<seecref="P:DotNetty.Transport.Channels.IChannel.IsWritable"/>), so that the pending write operations are
<seecref="T:DotNetty.Transport.Channels.Sockets.AbstractSocketChannel"/> base class for <seecref="T:DotNetty.Transport.Channels.IChannel"/>s that operate on bytes.
<seecref="T:DotNetty.Transport.Channels.Sockets.AbstractSocketChannel"/> base class for <seecref="T:DotNetty.Transport.Channels.IChannel"/>s that operate on messages.
Creates a new <seecref="T:DotNetty.Transport.Channels.Sockets.AbstractSocketMessageChannel"/> instance.
</summary>
<paramname="parent">The parent <seecref="T:DotNetty.Transport.Channels.IChannel"/>. Pass <c>null</c> if there's no parent.</param>
<paramname="socket">The <seecref="T:System.Net.Sockets.Socket"/> used by the <seecref="T:DotNetty.Transport.Channels.IChannel"/> for communication.</param>
Special event which will be fired and passed to the <seecref="M:DotNetty.Transport.Channels.IChannelHandler.UserEventTriggered(DotNetty.Transport.Channels.IChannelHandlerContext,System.Object)"/>
methods once the input of an <seecref="T:DotNetty.Transport.Channels.Sockets.ISocketChannel"/> was shutdown and the