1 /* 2 * Copyright 2012 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 * http://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.buffer.ByteBuf; 19 import io.netty.buffer.ByteBufAllocator; 20 import io.netty.util.AttributeKey; 21 import io.netty.util.AttributeMap; 22 import io.netty.util.concurrent.EventExecutor; 23 import io.netty.util.concurrent.FutureListener; 24 25 import java.net.ConnectException; 26 import java.net.SocketAddress; 27 import java.nio.channels.Channels; 28 29 /** 30 * Enables a [email protected] ChannelHandler} to interact with its [email protected] ChannelPipeline} 31 * and other handlers. Among other things a handler can notify the next [email protected] ChannelHandler} in the 32 * [email protected] ChannelPipeline} as well as modify the [email protected] ChannelPipeline} it belongs to dynamically. 33 * 34 * <h3>Notify</h3> 35 * 36 * You can notify the closest handler in the same [email protected] ChannelPipeline} by calling one of the various methods 37 * provided here. 38 * 39 * Please refer to [email protected] ChannelPipeline} to understand how an event flows. 40 * 41 * <h3>Modifying a pipeline</h3> 42 * 43 * You can get the [email protected] ChannelPipeline} your handler belongs to by calling 44 * [email protected] #pipeline()}. A non-trivial application could insert, remove, or 45 * replace handlers in the pipeline dynamically at runtime. 46 * 47 * <h3>Retrieving for later use</h3> 48 * 49 * You can keep the [email protected] ChannelHandlerContext} for later use, such as 50 * triggering an event outside the handler methods, even from a different thread. 51 * <pre> 52 * public class MyHandler extends [email protected] ChannelDuplexHandler} { 53 * 54 * <b>private [email protected] ChannelHandlerContext} ctx;</b> 55 * 56 * public void beforeAdd([email protected] ChannelHandlerContext} ctx) { 57 * <b>this.ctx = ctx;</b> 58 * } 59 * 60 * public void login(String username, password) { 61 * ctx.write(new LoginMessage(username, password)); 62 * } 63 * ... 64 * } 65 * </pre> 66 * 67 * <h3>Storing stateful information</h3> 68 * 69 * [email protected] #attr(AttributeKey)} allow you to 70 * store and access stateful information that is related with a handler and its 71 * context. Please refer to [email protected] ChannelHandler} to learn various recommended 72 * ways to manage stateful information. 73 * 74 * <h3>A handler can have more than one context</h3> 75 * 76 * Please note that a [email protected] ChannelHandler} instance can be added to more than 77 * one [email protected] ChannelPipeline}. It means a single [email protected] ChannelHandler} 78 * instance can have more than one [email protected] ChannelHandlerContext} and therefore 79 * the single instance can be invoked with different 80 * [email protected] ChannelHandlerContext}s if it is added to one or more 81 * [email protected] ChannelPipeline}s more than once. 82 * <p> 83 * For example, the following handler will have as many independent [email protected] AttributeKey}s 84 * as how many times it is added to pipelines, regardless if it is added to the 85 * same pipeline multiple times or added to different pipelines multiple times: 86 * <pre> 87 * public class FactorialHandler extends [email protected] ChannelInboundHandlerAdapter} { 88 * 89 * private final [email protected] AttributeKey}<[email protected] Integer}> counter = [email protected] AttributeKey}.valueOf("counter"); 90 * 91 * // This handler will receive a sequence of increasing integers starting 92 * // from 1. 93 * [email protected] @Override} 94 * public void channelRead([email protected] ChannelHandlerContext} ctx, Object msg) { 95 * Integer a = ctx.attr(counter).get(); 96 * 97 * if (a == null) { 98 * a = 1; 99 * } 100 * 101 * attr.set(a * (Integer) msg); 102 * } 103 * } 104 * 105 * // Different context objects are given to "f1", "f2", "f3", and "f4" even if 106 * // they refer to the same handler instance. Because the FactorialHandler 107 * // stores its state in a context object (using an [email protected] AttributeKey}), the factorial is 108 * // calculated correctly 4 times once the two pipelines (p1 and p2) are active. 109 * FactorialHandler fh = new FactorialHandler(); 110 * 111 * [email protected] ChannelPipeline} p1 = [email protected] Channels}.pipeline(); 112 * p1.addLast("f1", fh); 113 * p1.addLast("f2", fh); 114 * 115 * [email protected] ChannelPipeline} p2 = [email protected] Channels}.pipeline(); 116 * p2.addLast("f3", fh); 117 * p2.addLast("f4", fh); 118 * </pre> 119 * 120 * <h3>Additional resources worth reading</h3> 121 * <p> 122 * Please refer to the [email protected] ChannelHandler}, and 123 * [email protected] ChannelPipeline} to find out more about inbound and outbound operations, 124 * what fundamental differences they have, how they flow in a pipeline, and how to handle 125 * the operation in your application. 126 */ 127 public interface ChannelHandlerContext extends AttributeMap { 128 129 /** 130 * Return the [email protected] Channel} which is bound to the [email protected] ChannelHandlerContext}. 131 */ 132 Channel channel(); 133 134 /** 135 * Returns the [email protected] EventExecutor} which is used to execute an arbitrary task. 136 */ 137 EventExecutor executor(); 138 139 /** 140 * Returns the [email protected] ChannelHandlerInvoker} which is used to trigger an event for the associated 141 * [email protected] ChannelHandler}. Note that the methods in [email protected] ChannelHandlerInvoker} are not intended to be called 142 * by a user. Use this method only to obtain the reference to the [email protected] ChannelHandlerInvoker} 143 * (and not calling its methods) unless you know what you are doing. 144 */ 145 ChannelHandlerInvoker invoker(); 146 147 /** 148 * The unique name of the [email protected] ChannelHandlerContext}.The name was used when then [email protected] ChannelHandler} 149 * was added to the [email protected] ChannelPipeline}. This name can also be used to access the registered 150 * [email protected] ChannelHandler} from the [email protected] ChannelPipeline}. 151 */ 152 String name(); 153 154 /** 155 * The [email protected] ChannelHandler} that is bound this [email protected] ChannelHandlerContext}. 156 */ 157 ChannelHandler handler(); 158 159 /** 160 * Return [email protected] true} if the [email protected] ChannelHandler} which belongs to this context was removed 161 * from the [email protected] ChannelPipeline}. Note that this method is only meant to be called from with in the 162 * [email protected] EventLoop}. 163 */ 164 boolean isRemoved(); 165 166 /** 167 * A [email protected] Channel} was registered to its [email protected] EventLoop}. 168 * 169 * This will result in having the [email protected] ChannelInboundHandler#channelRegistered(ChannelHandlerContext)} method 170 * called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the 171 * [email protected] Channel}. 172 */ 173 ChannelHandlerContext fireChannelRegistered(); 174 175 /** 176 * A [email protected] Channel} was unregistered from its [email protected] EventLoop}. 177 * 178 * This will result in having the [email protected] ChannelInboundHandler#channelUnregistered(ChannelHandlerContext)} method 179 * called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the 180 * [email protected] Channel}. 181 */ 182 ChannelHandlerContext fireChannelUnregistered(); 183 184 /** 185 * A [email protected] Channel} is active now, which means it is connected. 186 * 187 * This will result in having the [email protected] ChannelInboundHandler#channelActive(ChannelHandlerContext)} method 188 * called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the 189 * [email protected] Channel}. 190 */ 191 ChannelHandlerContext fireChannelActive(); 192 193 /** 194 * A [email protected] Channel} is inactive now, which means it is closed. 195 * 196 * This will result in having the [email protected] ChannelInboundHandler#channelInactive(ChannelHandlerContext)} method 197 * called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the 198 * [email protected] Channel}. 199 */ 200 ChannelHandlerContext fireChannelInactive(); 201 202 /** 203 * A [email protected] Channel} received an [email protected] Throwable} in one of its inbound operations. 204 * 205 * This will result in having the [email protected] ChannelInboundHandler#exceptionCaught(ChannelHandlerContext, Throwable)} 206 * method called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the 207 * [email protected] Channel}. 208 */ 209 ChannelHandlerContext fireExceptionCaught(Throwable cause); 210 211 /** 212 * A [email protected] Channel} received an user defined event. 213 * 214 * This will result in having the [email protected] ChannelInboundHandler#userEventTriggered(ChannelHandlerContext, Object)} 215 * method called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the 216 * [email protected] Channel}. 217 */ 218 ChannelHandlerContext fireUserEventTriggered(Object event); 219 220 /** 221 * A [email protected] Channel} received a message. 222 * 223 * This will result in having the [email protected] ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)} 224 * method called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the 225 * [email protected] Channel}. 226 */ 227 ChannelHandlerContext fireChannelRead(Object msg); 228 229 /** 230 * Triggers an [email protected] ChannelInboundHandler#channelReadComplete(ChannelHandlerContext)} 231 * event to the next [email protected] ChannelInboundHandler} in the [email protected] ChannelPipeline}. 232 */ 233 ChannelHandlerContext fireChannelReadComplete(); 234 235 /** 236 * Triggers an [email protected] ChannelInboundHandler#channelWritabilityChanged(ChannelHandlerContext)} 237 * event to the next [email protected] ChannelInboundHandler} in the [email protected] ChannelPipeline}. 238 */ 239 ChannelHandlerContext fireChannelWritabilityChanged(); 240 241 /** 242 * Request to bind to the given [email protected] SocketAddress} and notify the [email protected] ChannelFuture} once the operation 243 * completes, either because the operation was successful or because of an error. 244 * <p> 245 * This will result in having the 246 * [email protected] ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method 247 * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 248 * {@link Channel}. 249 */ 250 ChannelFuture bind(SocketAddress localAddress); 251 252 /** 253 * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation 254 * completes, either because the operation was successful or because of an error. 255 * <p> 256 * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with 257 * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException} 258 * will be used. 259 * <p> 260 * This will result in having the 261 * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} 262 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 263 * {@link Channel}. 264 */ 265 ChannelFuture connect(SocketAddress remoteAddress); 266 267 /** 268 * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the 269 * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of 270 * an error. 271 * <p> 272 * This will result in having the 273 * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} 274 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 275 * {@link Channel}. 276 */ 277 ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress); 278 279 /** 280 * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes, 281 * either because the operation was successful or because of an error. 282 * <p> 283 * This will result in having the 284 * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)} 285 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 286 * {@link Channel}. 287 */ 288 ChannelFuture disconnect(); 289 290 /** 291 * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes, 292 * either because the operation was successful or because of 293 * an error. 294 * 295 * After it is closed it is not possible to reuse it again. 296 * <p> 297 * This will result in having the 298 * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)} 299 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 300 * {@link Channel}. 301 */ 302 ChannelFuture close(); 303 304 /** 305 * Request to deregister from the previous assigned {@link EventExecutor} and notify the 306 * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of 307 * an error. 308 * <p> 309 * This will result in having the 310 * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)} 311 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 312 * {@link Channel}. 313 * 314 */ 315 ChannelFuture deregister(); 316 317 /** 318 * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation 319 * completes, either because the operation was successful or because of an error. 320 * 321 * The given {@link ChannelPromise} will be notified. 322 * <p> 323 * This will result in having the 324 * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method 325 * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 326 * {@link Channel}. 327 */ 328 ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise); 329 330 /** 331 * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation 332 * completes, either because the operation was successful or because of an error. 333 * 334 * The given {@link ChannelFuture} will be notified. 335 * 336 * <p> 337 * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with 338 * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException} 339 * will be used. 340 * <p> 341 * This will result in having the 342 * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} 343 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 344 * {@link Channel}. 345 */ 346 ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise); 347 348 /** 349 * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the 350 * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of 351 * an error. 352 * 353 * The given {@link ChannelPromise} will be notified and also returned. 354 * <p> 355 * This will result in having the 356 * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)} 357 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 358 * {@link Channel}. 359 */ 360 ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise); 361 362 /** 363 * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes, 364 * either because the operation was successful or because of an error. 365 * 366 * The given {@link ChannelPromise} will be notified. 367 * <p> 368 * This will result in having the 369 * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)} 370 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 371 * {@link Channel}. 372 */ 373 ChannelFuture disconnect(ChannelPromise promise); 374 375 /** 376 * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes, 377 * either because the operation was successful or because of 378 * an error. 379 * 380 * After it is closed it is not possible to reuse it again. 381 * The given {@link ChannelPromise} will be notified. 382 * <p> 383 * This will result in having the 384 * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)} 385 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 386 * {@link Channel}. 387 */ 388 ChannelFuture close(ChannelPromise promise); 389 390 /** 391 * Request to deregister from the previous assigned {@link EventExecutor} and notify the 392 * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of 393 * an error. 394 * 395 * The given {@link ChannelPromise} will be notified. 396 * <p> 397 * This will result in having the 398 * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)} 399 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 400 * {@link Channel}. 401 */ 402 ChannelFuture deregister(ChannelPromise promise); 403 404 /** 405 * Request to Read data from the {@link Channel} into the first inbound buffer, triggers an 406 * {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)} event if data was 407 * read, and triggers a 408 * {@link ChannelInboundHandler#channelReadComplete(ChannelHandlerContext) channelReadComplete} event so the 409 * handler can decide to continue reading. If there's a pending read operation already, this method does nothing. 410 * <p> 411 * This will result in having the 412 * {@link ChannelOutboundHandler#read(ChannelHandlerContext)} 413 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the 414 * {@link Channel}. 415 */ 416 ChannelHandlerContext read(); 417 418 /** 419 * Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}. 420 * This method will not request to actual flush, so be sure to call {@link #flush()} 421 * once you want to request to flush all pending data to the actual transport. 422 */ 423 ChannelFuture write(Object msg); 424 425 /** 426 * Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}. 427 * This method will not request to actual flush, so be sure to call {@link #flush()} 428 * once you want to request to flush all pending data to the actual transport. 429 */ 430 ChannelFuture write(Object msg, ChannelPromise promise); 431 432 /** 433 * Request to flush all pending messages via this ChannelOutboundInvoker. 434 */ 435 ChannelHandlerContext flush(); 436 437 /** 438 * Shortcut for call {@link #write(Object, ChannelPromise)} and {@link #flush()}. 439 */ 440 ChannelFuture writeAndFlush(Object msg, ChannelPromise promise); 441 442 /** 443 * Shortcut for call {@link #write(Object)} and {@link #flush()}. 444 */ 445 ChannelFuture writeAndFlush(Object msg); 446 447 /** 448 * Return the assigned {@link ChannelPipeline} 449 */ 450 ChannelPipeline pipeline(); 451 452 /** 453 * Return the assigned {@link ByteBufAllocator} which will be used to allocate {@link ByteBuf}s. 454 */ 455 ByteBufAllocator alloc(); 456 457 /** 458 * Return a new {@link ChannelPromise}. 459 */ 460 ChannelPromise newPromise(); 461 462 /** 463 * Return an new {@link ChannelProgressivePromise} 464 */ 465 ChannelProgressivePromise newProgressivePromise(); 466 467 /** 468 * Create a new {@link ChannelFuture} which is marked as succeeded already. So {@link ChannelFuture#isSuccess()} 469 * will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also 470 * every call of blocking methods will just return without blocking. 471 */ 472 ChannelFuture newSucceededFuture(); 473 474 /** 475 * Create a new {@link ChannelFuture} which is marked as failed already. So {@link ChannelFuture#isSuccess()} 476 * will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also 477 * every call of blocking methods will just return without blocking. 478 */ 479 ChannelFuture newFailedFuture(Throwable cause); 480 481 /** 482 * Return a special ChannelPromise which can be reused for different operations. 483 * <p> 484 * It's only supported to use 485 * it for {@link ChannelHandlerContext#write(Object, ChannelPromise)}. 486 * </p> 487 * <p> 488 * Be aware that the returned {@link ChannelPromise} will not support most operations and should only be used 489 * if you want to save an object allocation for every write operation. You will not be able to detect if the 490 * operation was complete, only if it failed as the implementation will call 491 * {@link ChannelPipeline#fireExceptionCaught(Throwable)} in this case. 492 * </p> 493 * <strong>Be aware this is an expert feature and should be used with care!</strong> 494 */ 495 ChannelPromise voidPromise(); 496 497 }