io.netty.channel.ChannelPipeline Maven / Gradle / Ivy
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.channel;
import io.netty.buffer.ByteBuf;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.EventExecutorGroup;
import java.net.ConnectException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
/**
* A list of {@link ChannelHandler}s which handles or intercepts inbound events and outbound operations of a
* {@link Channel}. {@link ChannelPipeline} implements an advanced form of the
* Intercepting Filter pattern
* to give a user full control over how an event is handled and how the {@link ChannelHandler}s in a pipeline
* interact with each other.
*
* Creation of a pipeline
*
* Each channel has its own pipeline and it is created automatically when a new channel is created.
*
* How an event flows in a pipeline
*
* The following diagram describes how I/O events are processed by {@link ChannelHandler}s in a {@link ChannelPipeline}
* typically. An I/O event is handled by a {@link ChannelHandler} and is forwarded by the {@link ChannelHandler} which
* handled the event to the {@link ChannelHandler} which is placed right next to it. A {@link ChannelHandler} can also
* trigger an arbitrary I/O event if necessary. To forward or trigger an event, a {@link ChannelHandler} calls the
* event propagation methods defined in {@link ChannelHandlerContext}, such as
* {@link ChannelHandlerContext#fireChannelRead(Object)} and {@link ChannelHandlerContext#write(Object)}.
*
* I/O Request
* via {@link Channel} or
* {@link ChannelHandlerContext}
* |
* +---------------------------------------------------+---------------+
* | ChannelPipeline | |
* | \|/ |
* | +----------------------------------------------+----------+ |
* | | ChannelHandler N | |
* | +----------+-----------------------------------+----------+ |
* | /|\ | |
* | | \|/ |
* | +----------+-----------------------------------+----------+ |
* | | ChannelHandler N-1 | |
* | +----------+-----------------------------------+----------+ |
* | /|\ . |
* | . . |
* | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
* | [method call] [method call] |
* | . . |
* | . \|/ |
* | +----------+-----------------------------------+----------+ |
* | | ChannelHandler 2 | |
* | +----------+-----------------------------------+----------+ |
* | /|\ | |
* | | \|/ |
* | +----------+-----------------------------------+----------+ |
* | | ChannelHandler 1 | |
* | +----------+-----------------------------------+----------+ |
* | /|\ | |
* +---------------+-----------------------------------+---------------+
* | \|/
* +---------------+-----------------------------------+---------------+
* | | | |
* | [ Socket.read() ] [ Socket.write() ] |
* | |
* | Netty Internal I/O Threads (Transport Implementation) |
* +-------------------------------------------------------------------+
*
* An inbound event is handled by the {@link ChannelHandler}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
* {@link ChannelHandler}s are notified when the state of a {@link Channel} 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
* {@link ChannelHandler} at the top of the diagram, it is discarded and logged, depending on your loglevel.
*
*
* An outbound event is handled by the {@link ChannelHandler}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 {@link ChannelHandler} at the
* bottom of the diagram, it is handled by an I/O thread associated with the {@link Channel}. The I/O thread often
* performs the actual output operation such as {@link SocketChannel#write(ByteBuffer)}.
*
*
*
Forwarding an event to the next handler
*
* As explained briefly above, a {@link ChannelHandler} has to invoke the event propagation methods in
* {@link ChannelHandlerContext} to forward an event to its next handler. Those methods include:
*
* - Inbound event propagation methods:
*
* - {@link ChannelHandlerContext#fireChannelRegistered()}
* - {@link ChannelHandlerContext#fireChannelActive()}
* - {@link ChannelHandlerContext#fireChannelRead(Object)}
* - {@link ChannelHandlerContext#fireChannelReadComplete()}
* - {@link ChannelHandlerContext#fireExceptionCaught(Throwable)}
* - {@link ChannelHandlerContext#fireUserEventTriggered(Object)}
* - {@link ChannelHandlerContext#fireChannelWritabilityChanged()}
* - {@link ChannelHandlerContext#fireChannelInactive()}
*
*
* - Outbound event propagation methods:
*
* - {@link ChannelHandlerContext#bind(SocketAddress, ChannelPromise)}
* - {@link ChannelHandlerContext#connect(SocketAddress, SocketAddress, ChannelPromise)}
* - {@link ChannelHandlerContext#write(Object, ChannelPromise)}
* - {@link ChannelHandlerContext#flush()}
* - {@link ChannelHandlerContext#read()}
* - {@link ChannelHandlerContext#disconnect(ChannelPromise)}
* - {@link ChannelHandlerContext#close(ChannelPromise)}
*
*
*
*
* and the following example shows how the event propagation is usually done:
*
*
* public class MyInboundHandler extends {@link ChannelHandlerAdapter} {
* {@code @Override}
* public void channelActive({@link ChannelHandlerContext} ctx) {
* System.out.println("Connected!");
* ctx.fireChannelActive();
* }
* }
*
* public clas MyOutboundHandler extends {@link ChannelHandlerAdapter} {
* {@code @Override}
* public void close({@link ChannelHandlerContext} ctx, {@link ChannelPromise} promise) {
* System.out.println("Closing ..");
* ctx.close(promise);
* }
* }
*
*
* Building a pipeline
*
* A user is supposed to have one or more {@link ChannelHandler}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:
*
*
* - Protocol Decoder - translates binary data (e.g. {@link ByteBuf}) into a Java object.
* - Protocol Encoder - translates a Java object into binary data.
* - Business Logic Handler - performs the actual business logic (e.g. database access).
*
*
* and it could be represented as shown in the following example:
*
*
* static final {@link EventExecutorGroup} group = new {@link DefaultEventExecutorGroup}(16);
* ...
*
* {@link ChannelPipeline} pipeline = ch.pipeline();
*
* 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());
*
*
* Thread safety
*
* A {@link ChannelHandler} can be added or removed at any time because a {@link ChannelPipeline} is thread safe.
* For example, you can insert an encryption handler when sensitive information is about to be exchanged, and remove it
* after the exchange.
*/
public interface ChannelPipeline extends Iterable> {
/**
* Inserts a {@link ChannelHandler} at the first position of this pipeline.
*
* @param name the name of the handler to insert first. {@code null} to let the name auto-generated.
* @param handler the handler to insert first
*
* @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline
* @throws NullPointerException
* if the specified handler is {@code null}
*/
ChannelPipeline addFirst(String name, ChannelHandler handler);
/**
* Inserts a {@link ChannelHandler} at the first position of this pipeline.
*
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
* methods
* @param name the name of the handler to insert first. {@code null} to let the name auto-generated.
* @param handler the handler to insert first
*
* @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline
* @throws NullPointerException
* if the specified handler is {@code null}
*/
ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);
/**
* Inserts a {@link ChannelHandler} at the first position of this pipeline.
*
* @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
* @param name the name of the handler to insert first. {@code null} to let the name auto-generated.
* @param handler the handler to insert first
*
* @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline
* @throws NullPointerException
* if the specified handler is {@code null}
*/
ChannelPipeline addFirst(ChannelHandlerInvoker invoker, String name, ChannelHandler handler);
/**
* Appends a {@link ChannelHandler} at the last position of this pipeline.
*
* @param name the name of the handler to append. {@code null} to let the name auto-generated.
* @param handler the handler to append
*
* @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline
* @throws NullPointerException
* if the specified handler is {@code null}
*/
ChannelPipeline addLast(String name, ChannelHandler handler);
/**
* Appends a {@link ChannelHandler} at the last position of this pipeline.
*
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
* methods
* @param name the name of the handler to append. {@code null} to let the name auto-generated.
* @param handler the handler to append
*
* @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline
* @throws NullPointerException
* if the specified handler is {@code null}
*/
ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);
/**
* Appends a {@link ChannelHandler} at the last position of this pipeline.
*
* @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
* @param name the name of the handler to append. {@code null} to let the name auto-generated.
* @param handler the handler to append
*
* @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline
* @throws NullPointerException
* if the specified handler is {@code null}
*/
ChannelPipeline addLast(ChannelHandlerInvoker invoker, String name, ChannelHandler handler);
/**
* Inserts a {@link ChannelHandler} before an existing handler of this
* pipeline.
*
* @param baseName the name of the existing handler
* @param name the name of the handler to insert before. {@code null} to let the name auto-generated.
* @param handler the handler to insert before
*
* @throws NoSuchElementException
* if there's no such entry with the specified {@code baseName}
* @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline
* @throws NullPointerException
* if the specified baseName or handler is {@code null}
*/
ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);
/**
* Inserts a {@link ChannelHandler} before an existing handler of this
* pipeline.
*
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
* methods
* @param baseName the name of the existing handler
* @param name the name of the handler to insert before. {@code null} to let the name auto-generated.
* @param handler the handler to insert before
*
* @throws NoSuchElementException
* if there's no such entry with the specified {@code baseName}
* @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline
* @throws NullPointerException
* if the specified baseName or handler is {@code null}
*/
ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
/**
* Inserts a {@link ChannelHandler} before an existing handler of this
* pipeline.
*
* @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
* @param baseName the name of the existing handler
* @param name the name of the handler to insert before. {@code null} to let the name auto-generated.
* @param handler the handler to insert before
*
* @throws NoSuchElementException
* if there's no such entry with the specified {@code baseName}
* @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline
* @throws NullPointerException
* if the specified baseName or handler is {@code null}
*/
ChannelPipeline addBefore(ChannelHandlerInvoker invoker, String baseName, String name, ChannelHandler handler);
/**
* Inserts a {@link ChannelHandler} after an existing handler of this
* pipeline.
*
* @param baseName the name of the existing handler
* @param name the name of the handler to insert after. {@code null} to let the name auto-generated.
* @param handler the handler to insert after
*
* @throws NoSuchElementException
* if there's no such entry with the specified {@code baseName}
* @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline
* @throws NullPointerException
* if the specified baseName or handler is {@code null}
*/
ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);
/**
* Inserts a {@link ChannelHandler} after an existing handler of this
* pipeline.
*
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
* methods
* @param baseName the name of the existing handler
* @param name the name of the handler to insert after. {@code null} to let the name auto-generated.
* @param handler the handler to insert after
*
* @throws NoSuchElementException
* if there's no such entry with the specified {@code baseName}
* @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline
* @throws NullPointerException
* if the specified baseName or handler is {@code null}
*/
ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
/**
* Inserts a {@link ChannelHandler} after an existing handler of this
* pipeline.
*
* @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
* @param baseName the name of the existing handler
* @param name the name of the handler to insert after. {@code null} to let the name auto-generated.
* @param handler the handler to insert after
*
* @throws NoSuchElementException
* if there's no such entry with the specified {@code baseName}
* @throws IllegalArgumentException
* if there's an entry with the same name already in the pipeline
* @throws NullPointerException
* if the specified baseName or handler is {@code null}
*/
ChannelPipeline addAfter(ChannelHandlerInvoker invoker, String baseName, String name, ChannelHandler handler);
/**
* Inserts a {@link ChannelHandler}s at the first position of this pipeline.
*
* @param handlers the handlers to insert first
*
*/
ChannelPipeline addFirst(ChannelHandler... handlers);
/**
* Inserts a {@link ChannelHandler}s at the first position of this pipeline.
*
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}s
* methods.
* @param handlers the handlers to insert first
*
*/
ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers);
/**
* Inserts a {@link ChannelHandler}s at the first position of this pipeline.
*
* @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
* @param handlers the handlers to insert first
*
*/
ChannelPipeline addFirst(ChannelHandlerInvoker invoker, ChannelHandler... handlers);
/**
* Inserts a {@link ChannelHandler}s at the last position of this pipeline.
*
* @param handlers the handlers to insert last
*
*/
ChannelPipeline addLast(ChannelHandler... handlers);
/**
* Inserts a {@link ChannelHandler}s at the last position of this pipeline.
*
* @param group the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}s
* methods.
* @param handlers the handlers to insert last
*
*/
ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers);
/**
* Inserts a {@link ChannelHandler}s at the last position of this pipeline.
*
* @param invoker the {@link ChannelHandlerInvoker} which invokes the {@code handler}s event handler methods
* @param handlers the handlers to insert last
*
*/
ChannelPipeline addLast(ChannelHandlerInvoker invoker, ChannelHandler... handlers);
/**
* Removes the specified {@link ChannelHandler} from this pipeline.
*
* @param handler the {@link ChannelHandler} to remove
*
* @throws NoSuchElementException
* if there's no such handler in this pipeline
* @throws NullPointerException
* if the specified handler is {@code null}
*/
ChannelPipeline remove(ChannelHandler handler);
/**
* Removes the {@link ChannelHandler} with the specified name from this pipeline.
*
* @param name the name under which the {@link ChannelHandler} was stored.
*
* @return the removed handler
*
* @throws NoSuchElementException
* if there's no such handler with the specified name in this pipeline
* @throws NullPointerException
* if the specified name is {@code null}
*/
ChannelHandler remove(String name);
/**
* Removes the {@link ChannelHandler} of the specified type from this pipeline.
*
* @param the type of the handler
* @param handlerType the type of the handler
*
* @return the removed handler
*
* @throws NoSuchElementException
* if there's no such handler of the specified type in this pipeline
* @throws NullPointerException
* if the specified handler type is {@code null}
*/
T remove(Class handlerType);
/**
* Removes the first {@link ChannelHandler} in this pipeline.
*
* @return the removed handler
*
* @throws NoSuchElementException
* if this pipeline is empty
*/
ChannelHandler removeFirst();
/**
* Removes the last {@link ChannelHandler} in this pipeline.
*
* @return the removed handler
*
* @throws NoSuchElementException
* if this pipeline is empty
*/
ChannelHandler removeLast();
/**
* Replaces the specified {@link ChannelHandler} with a new handler in this pipeline.
*
* @param oldHandler the {@link ChannelHandler} to be replaced
* @param newName the name under which the replacement should be added.
* {@code null} to use the same name with the handler being replaced.
* @param newHandler the {@link ChannelHandler} which is used as replacement
*
* @return itself
* @throws NoSuchElementException
* if the specified old handler does not exist in this pipeline
* @throws IllegalArgumentException
* if a handler with the specified new name already exists in this
* pipeline, except for the handler to be replaced
* @throws NullPointerException
* if the specified old handler or new handler is {@code null}
*/
ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);
/**
* Replaces the {@link ChannelHandler} of the specified name with a new handler in this pipeline.
*
* @param oldName the name of the {@link ChannelHandler} to be replaced
* @param newName the name under which the replacement should be added.
* {@code null} to use the same name with the handler being replaced.
* @param newHandler the {@link ChannelHandler} which is used as replacement
*
* @return the removed handler
*
* @throws NoSuchElementException
* if the handler with the specified old name does not exist in this pipeline
* @throws IllegalArgumentException
* if a handler with the specified new name already exists in this
* pipeline, except for the handler to be replaced
* @throws NullPointerException
* if the specified old handler or new handler is {@code null}
*/
ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);
/**
* Replaces the {@link ChannelHandler} of the specified type with a new handler in this pipeline.
*
* @param oldHandlerType the type of the handler to be removed
* @param newName the name under which the replacement should be added.
* {@code null} to use the same name with the handler being replaced.
* @param newHandler the {@link ChannelHandler} which is used as replacement
*
* @return the removed handler
*
* @throws NoSuchElementException
* if the handler of the specified old handler type does not exist
* in this pipeline
* @throws IllegalArgumentException
* if a handler with the specified new name already exists in this
* pipeline, except for the handler to be replaced
* @throws NullPointerException
* if the specified old handler or new handler is {@code null}
*/
T replace(Class oldHandlerType, String newName,
ChannelHandler newHandler);
/**
* Returns the first {@link ChannelHandler} in this pipeline.
*
* @return the first handler. {@code null} if this pipeline is empty.
*/
ChannelHandler first();
/**
* Returns the context of the first {@link ChannelHandler} in this pipeline.
*
* @return the context of the first handler. {@code null} if this pipeline is empty.
*/
ChannelHandlerContext firstContext();
/**
* Returns the last {@link ChannelHandler} in this pipeline.
*
* @return the last handler. {@code null} if this pipeline is empty.
*/
ChannelHandler last();
/**
* Returns the context of the last {@link ChannelHandler} in this pipeline.
*
* @return the context of the last handler. {@code null} if this pipeline is empty.
*/
ChannelHandlerContext lastContext();
/**
* Returns the {@link ChannelHandler} with the specified name in this
* pipeline.
*
* @return the handler with the specified name.
* {@code null} if there's no such handler in this pipeline.
*/
ChannelHandler get(String name);
/**
* Returns the {@link ChannelHandler} of the specified type in this
* pipeline.
*
* @return the handler of the specified handler type.
* {@code null} if there's no such handler in this pipeline.
*/
T get(Class handlerType);
/**
* Returns the context object of the specified {@link ChannelHandler} in
* this pipeline.
*
* @return the context object of the specified handler.
* {@code null} if there's no such handler in this pipeline.
*/
ChannelHandlerContext context(ChannelHandler handler);
/**
* Returns the context object of the {@link ChannelHandler} with the
* specified name in this pipeline.
*
* @return the context object of the handler with the specified name.
* {@code null} if there's no such handler in this pipeline.
*/
ChannelHandlerContext context(String name);
/**
* Returns the context object of the {@link ChannelHandler} of the
* specified type in this pipeline.
*
* @return the context object of the handler of the specified type.
* {@code null} if there's no such handler in this pipeline.
*/
ChannelHandlerContext context(Class extends ChannelHandler> handlerType);
/**
* Returns the {@link Channel} that this pipeline is attached to.
*
* @return the channel. {@code null} if this pipeline is not attached yet.
*/
Channel channel();
/**
* Returns the {@link List} of the handler names.
*/
List names();
/**
* Converts this pipeline into an ordered {@link Map} whose keys are
* handler names and whose values are handlers.
*/
Map toMap();
/**
* A {@link Channel} was registered to its {@link EventLoop}.
*
* This will result in having the {@link ChannelHandler#channelRegistered(ChannelHandlerContext)} method
* called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
*/
ChannelPipeline fireChannelRegistered();
/**
* A {@link Channel} was unregistered from its {@link EventLoop}.
*
* This will result in having the {@link ChannelHandler#channelUnregistered(ChannelHandlerContext)} method
* called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
*/
ChannelPipeline fireChannelUnregistered();
/**
* A {@link Channel} is active now, which means it is connected.
*
* This will result in having the {@link ChannelHandler#channelActive(ChannelHandlerContext)} method
* called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
*/
ChannelPipeline fireChannelActive();
/**
* A {@link Channel} is inactive now, which means it is closed.
*
* This will result in having the {@link ChannelHandler#channelInactive(ChannelHandlerContext)} method
* called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
*/
ChannelPipeline fireChannelInactive();
/**
* A {@link Channel} received an {@link Throwable} in one of its inbound operations.
*
* This will result in having the {@link ChannelHandler#exceptionCaught(ChannelHandlerContext, Throwable)}
* method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
*/
ChannelPipeline fireExceptionCaught(Throwable cause);
/**
* A {@link Channel} received an user defined event.
*
* This will result in having the {@link ChannelHandler#userEventTriggered(ChannelHandlerContext, Object)}
* method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
*/
ChannelPipeline fireUserEventTriggered(Object event);
/**
* A {@link Channel} received a message.
*
* This will result in having the {@link ChannelHandler#channelRead(ChannelHandlerContext, Object)}
* method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
* {@link Channel}.
*/
ChannelPipeline fireChannelRead(Object msg);
/**
* Triggers an {@link ChannelHandler#channelWritabilityChanged(ChannelHandlerContext)}
* event to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
*/
ChannelPipeline fireChannelReadComplete();
/**
* Triggers an {@link ChannelHandler#channelWritabilityChanged(ChannelHandlerContext)}
* event to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
*/
ChannelPipeline fireChannelWritabilityChanged();
/**
* 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 the {@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 the {@link Channel} from the previous assigned {@link EventExecutor} 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}.
*
*/
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 the {@link Channel} bound to this {@link ChannelPipeline} 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 the {@link Channel} bound this {@link ChannelPipeline} from the previous assigned
* {@link EventExecutor} 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.
*
ChannelOutboundHandler
* 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}.
*/
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}.
*/
ChannelPipeline read();
/**
* Request to write a message via this {@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 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.
*/
ChannelPipeline 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);
}