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