/* * 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.buffer.ByteBufAllocator; import io.netty.channel.socket.DatagramChannel; import io.netty.channel.socket.DatagramPacket; import io.netty.channel.socket.ServerSocketChannel; import io.netty.channel.socket.SocketChannel; import io.netty.util.AttributeMap; import io.netty.util.concurrent.FutureListener; import java.net.ConnectException; import java.net.InetSocketAddress; import java.net.SocketAddress; /** * A nexus to a network socket or a component which is capable of I/O * operations such as read, write, connect, and bind. *
* A channel provides a user: *
* All I/O operations in Netty are asynchronous. It means any I/O calls will * return immediately with no guarantee that the requested I/O operation has * been completed at the end of the call. Instead, you will be returned with * a {@link ChannelFuture} instance which will notify you when the requested I/O * operation has succeeded, failed, or canceled. * *
* A {@link Channel} can have a {@linkplain #parent() parent} depending on * how it was created. For instance, a {@link SocketChannel}, that was accepted * 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. * *
* 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}. * *
* 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.
*/
public interface Channel extends AttributeMap, Comparable
* 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.
*
* 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 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 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);
/**
* Unsafe operations that should never be called from user-code. These methods
* are only provided to implement the actual transport, and must be invoked from an I/O thread except for the
* following methods:
*
*
*/
interface Unsafe {
/**
* Returns the {@link ChannelHandlerInvoker} which is used by default unless specified by a user.
*/
ChannelHandlerInvoker invoker();
/**
* Return the {@link SocketAddress} to which is bound local or
* {@code null} if none.
*/
SocketAddress localAddress();
/**
* Return the {@link SocketAddress} to which is bound remote or
* {@code null} if none is bound yet.
*/
SocketAddress remoteAddress();
/**
* Register the {@link Channel} of the {@link ChannelPromise} and notify
* the {@link ChannelFuture} once the registration was complete.
*/
void register(ChannelPromise promise);
/**
* Bind the {@link SocketAddress} to the {@link Channel} of the {@link ChannelPromise} and notify
* it once its done.
*/
void bind(SocketAddress localAddress, ChannelPromise promise);
/**
* Connect the {@link Channel} of the given {@link ChannelFuture} with the given remote {@link SocketAddress}.
* If a specific local {@link SocketAddress} should be used it need to be given as argument. Otherwise just
* pass {@code null} to it.
*
* The {@link ChannelPromise} will get notified once the connect operation was complete.
*/
void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);
/**
* Disconnect the {@link Channel} of the {@link ChannelFuture} and notify the {@link ChannelPromise} once the
* operation was complete.
*/
void disconnect(ChannelPromise promise);
/**
* Close the {@link Channel} of the {@link ChannelPromise} and notify the {@link ChannelPromise} once the
* operation was complete.
*/
void close(ChannelPromise promise);
/**
* Closes the {@link Channel} immediately without firing any events. Probably only useful
* when registration attempt failed.
*/
void closeForcibly();
/**
* Schedules a read operation that fills the inbound buffer of the first {@link ChannelHandler} in the
* {@link ChannelPipeline}. If there's already a pending read operation, this method does nothing.
*/
void beginRead();
/**
* Schedules a write operation.
*/
void write(Object msg, ChannelPromise promise);
/**
* Flush out all write operations scheduled via {@link #write(Object, ChannelPromise)}.
*/
void flush();
/**
* Return a special ChannelPromise which can be reused and passed to the operations in {@link Unsafe}.
* It will never be notified of a success or error and so is only a placeholder for operations
* that take a {@link ChannelPromise} as argument but for which you not want to get notified.
*/
ChannelPromise voidPromise();
/**
* Returns the {@link ChannelOutboundBuffer} of the {@link Channel} where the pending write requests are stored.
*/
ChannelOutboundBuffer outboundBuffer();
}
}