1 /* 2 * Copyright 2016 The Netty Project 3 * 4 * The Netty Project licenses this file to you under the Apache License, 5 * version 2.0 (the "License"); you may not use this file except in compliance 6 * with the License. You may obtain a copy of the License at: 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 package io.netty.channel; 17 18 import io.netty.util.concurrent.EventExecutor; 19 import io.netty.util.concurrent.FutureListener; 20 21 import java.net.ConnectException; 22 import java.net.SocketAddress; 23 24 public interface ChannelOutboundInvoker { 25 26 /** 27 * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation 28 * completes, either because the operation was successful or because of an error. 29 * <p> 30 * This will result in having the 31 * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method 32 * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 33 * {@link Channel}. 34 */ 35 default ChannelFuture bind(SocketAddress localAddress) { 36 return bind(localAddress, newPromise()); 37 } 38 39 /** 40 * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation 41 * completes, either because the operation was successful or because of an error. 42 * <p> 43 * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with 44 * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException} 45 * will be used. 46 * <p> 47 * This will result in having the 48 * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} 49 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 50 * {@link Channel}. 51 */ 52 default ChannelFuture connect(SocketAddress remoteAddress) { 53 return connect(remoteAddress, newPromise()); 54 } 55 56 /** 57 * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the 58 * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of 59 * an error. 60 * <p> 61 * This will result in having the 62 * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} 63 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 64 * {@link Channel}. 65 */ 66 default ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) { 67 return connect(remoteAddress, localAddress, newPromise()); 68 } 69 70 /** 71 * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes, 72 * either because the operation was successful or because of an error. 73 * <p> 74 * This will result in having the 75 * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)} 76 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 77 * {@link Channel}. 78 */ 79 default ChannelFuture disconnect() { 80 return disconnect(newPromise()); 81 } 82 83 /** 84 * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes, 85 * either because the operation was successful or because of 86 * an error. 87 * 88 * After it is closed it is not possible to reuse it again. 89 * <p> 90 * This will result in having the 91 * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)} 92 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 93 * {@link Channel}. 94 */ 95 default ChannelFuture close() { 96 return close(newPromise()); 97 } 98 99 /** 100 * Request to deregister from the previous assigned {@link EventExecutor} and notify the 101 * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of 102 * an error. 103 * <p> 104 * This will result in having the 105 * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)} 106 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 107 * {@link Channel}. 108 * 109 */ 110 default ChannelFuture deregister() { 111 return deregister(newPromise()); 112 } 113 114 /** 115 * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation 116 * completes, either because the operation was successful or because of an error. 117 * 118 * The given {@link ChannelPromise} will be notified. 119 * <p> 120 * This will result in having the 121 * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method 122 * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 123 * {@link Channel}. 124 */ 125 ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise); 126 127 /** 128 * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation 129 * completes, either because the operation was successful or because of an error. 130 * 131 * The given {@link ChannelFuture} will be notified. 132 * 133 * <p> 134 * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with 135 * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException} 136 * will be used. 137 * <p> 138 * This will result in having the 139 * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} 140 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 141 * {@link Channel}. 142 */ 143 ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise); 144 145 /** 146 * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the 147 * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of 148 * an error. 149 * 150 * The given {@link ChannelPromise} will be notified and also returned. 151 * <p> 152 * This will result in having the 153 * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} 154 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 155 * {@link Channel}. 156 */ 157 ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise); 158 159 /** 160 * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes, 161 * either because the operation was successful or because of an error. 162 * 163 * The given {@link ChannelPromise} will be notified. 164 * <p> 165 * This will result in having the 166 * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)} 167 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 168 * {@link Channel}. 169 */ 170 ChannelFuture disconnect(ChannelPromise promise); 171 172 /** 173 * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes, 174 * either because the operation was successful or because of 175 * an error. 176 * 177 * After it is closed it is not possible to reuse it again. 178 * The given {@link ChannelPromise} will be notified. 179 * <p> 180 * This will result in having the 181 * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)} 182 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 183 * {@link Channel}. 184 */ 185 ChannelFuture close(ChannelPromise promise); 186 187 /** 188 * Request to deregister from the previous assigned {@link EventExecutor} and notify the 189 * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of 190 * an error. 191 * 192 * The given {@link ChannelPromise} will be notified. 193 * <p> 194 * This will result in having the 195 * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)} 196 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 197 * {@link Channel}. 198 */ 199 ChannelFuture deregister(ChannelPromise promise); 200 201 /** 202 * Request to Read data from the {@link Channel} into the first inbound buffer, triggers an 203 * {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)} event if data was 204 * read, and triggers a 205 * {@link ChannelInboundHandler#channelReadComplete(ChannelHandlerContext) channelReadComplete} event so the 206 * handler can decide to continue reading. If there's a pending read operation already, this method does nothing. 207 * <p> 208 * This will result in having the 209 * {@link ChannelOutboundHandler#read(ChannelHandlerContext)} 210 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 211 * {@link Channel}. 212 */ 213 ChannelOutboundInvoker read(); 214 215 /** 216 * Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}. 217 * This method will not request to actual flush, so be sure to call {@link #flush()} 218 * once you want to request to flush all pending data to the actual transport. 219 */ 220 default ChannelFuture write(Object msg) { 221 return write(msg, newPromise()); 222 } 223 224 /** 225 * Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}. 226 * This method will not request to actual flush, so be sure to call {@link #flush()} 227 * once you want to request to flush all pending data to the actual transport. 228 */ 229 ChannelFuture write(Object msg, ChannelPromise promise); 230 231 /** 232 * Request to flush all pending messages via this ChannelOutboundInvoker. 233 */ 234 ChannelOutboundInvoker flush(); 235 236 /** 237 * Shortcut for call {@link #write(Object, ChannelPromise)} and {@link #flush()}. 238 */ 239 ChannelFuture writeAndFlush(Object msg, ChannelPromise promise); 240 241 /** 242 * Shortcut for call {@link #write(Object)} and {@link #flush()}. 243 */ 244 default ChannelFuture writeAndFlush(Object msg) { 245 return writeAndFlush(msg, newPromise()); 246 } 247 248 /** 249 * Return a new {@link ChannelPromise}. 250 */ 251 ChannelPromise newPromise(); 252 253 /** 254 * Return an new {@link ChannelProgressivePromise} 255 */ 256 ChannelProgressivePromise newProgressivePromise(); 257 258 /** 259 * Create a new {@link ChannelFuture} which is marked as succeeded already. So {@link ChannelFuture#isSuccess()} 260 * will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also 261 * every call of blocking methods will just return without blocking. 262 */ 263 ChannelFuture newSucceededFuture(); 264 265 /** 266 * Create a new {@link ChannelFuture} which is marked as failed already. So {@link ChannelFuture#isSuccess()} 267 * will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also 268 * every call of blocking methods will just return without blocking. 269 */ 270 ChannelFuture newFailedFuture(Throwable cause); 271 272 /** 273 * Return a special ChannelPromise which can be reused for different operations. 274 * <p> 275 * It's only supported to use 276 * it for {@link ChannelOutboundInvoker#write(Object, ChannelPromise)}. 277 * </p> 278 * <p> 279 * Be aware that the returned {@link ChannelPromise} will not support most operations and should only be used 280 * if you want to save an object allocation for every write operation. You will not be able to detect if the 281 * operation was complete, only if it failed as the implementation will call 282 * {@link ChannelPipeline#fireExceptionCaught(Throwable)} in this case. 283 * </p> 284 * <strong>Be aware this is an expert feature and should be used with care!</strong> 285 */ 286 ChannelPromise voidPromise(); 287 }