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 org.jboss.netty.channel.group;
17
18 import java.net.SocketAddress;
19 import java.util.Set;
20
21 import org.jboss.netty.bootstrap.ServerBootstrap;
22 import org.jboss.netty.buffer.ChannelBuffer;
23 import org.jboss.netty.buffer.ChannelBuffers;
24 import org.jboss.netty.channel.Channel;
25 import org.jboss.netty.channel.ChannelHandlerContext;
26 import org.jboss.netty.channel.ChannelStateEvent;
27 import org.jboss.netty.channel.ServerChannel;
28 import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
29 import org.jboss.netty.util.CharsetUtil;
30
31 /**
32 * A thread-safe {@link Set} that contains open {@link Channel}s and provides
33 * various bulk operations on them. Using {@link ChannelGroup}, you can
34 * categorize {@link Channel}s into a meaningful group (e.g. on a per-service
35 * or per-state basis.) A closed {@link Channel} is automatically removed from
36 * the collection, so that you don't need to worry about the life cycle of the
37 * added {@link Channel}. A {@link Channel} can belong to more than one
38 * {@link ChannelGroup}.
39 *
40 * <h3>Broadcast a message to multiple {@link Channel}s</h3>
41 * <p>
42 * If you need to broadcast a message to more than one {@link Channel}, you can
43 * add the {@link Channel}s associated with the recipients and call {@link ChannelGroup#write(Object)}:
44 * <pre>
45 * <strong>{@link ChannelGroup} recipients = new {@link DefaultChannelGroup}();</strong>
46 * recipients.add(channelA);
47 * recipients.add(channelB);
48 * ..
49 * <strong>recipients.write({@link ChannelBuffers}.copiedBuffer(
50 * "Service will shut down for maintenance in 5 minutes.",
51 * {@link CharsetUtil}.UTF_8));</strong>
52 * </pre>
53 *
54 * <h3>Simplify shutdown process with {@link ChannelGroup}</h3>
55 * <p>
56 * If both {@link ServerChannel}s and non-{@link ServerChannel}s exist in the
57 * same {@link ChannelGroup}, any requested I/O operations on the group are
58 * performed for the {@link ServerChannel}s first and then for the others.
59 * <p>
60 * This rule is very useful when you shut down a server in one shot:
61 *
62 * <pre>
63 * <strong>{@link ChannelGroup} allChannels = new {@link DefaultChannelGroup}();</strong>
64 *
65 * public static void main(String[] args) throws Exception {
66 * {@link ServerBootstrap} b = new {@link ServerBootstrap}(..);
67 * ...
68 *
69 * // Start the server
70 * b.getPipeline().addLast("handler", new MyHandler());
71 * {@link Channel} serverChannel = b.bind(..);
72 * <strong>allChannels.add(serverChannel);</strong>
73 *
74 * ... Wait until the shutdown signal reception ...
75 *
76 * // Close the serverChannel and then all accepted connections.
77 * <strong>allChannels.close().awaitUninterruptibly();</strong>
78 * b.releaseExternalResources();
79 * }
80 *
81 * public class MyHandler extends {@link SimpleChannelUpstreamHandler} {
82 * {@code @Override}
83 * public void channelOpen({@link ChannelHandlerContext} ctx, {@link ChannelStateEvent} e) {
84 * // Add all open channels to the global group so that they are
85 * // closed on shutdown.
86 * <strong>allChannels.add(e.getChannel());</strong>
87 * }
88 * }
89 * </pre>
90 * @apiviz.landmark
91 * @apiviz.has org.jboss.netty.channel.group.ChannelGroupFuture oneway - - returns
92 */
93 public interface ChannelGroup extends Set<Channel>, Comparable<ChannelGroup> {
94
95 /**
96 * Returns the name of this group. A group name is purely for helping
97 * you to distinguish one group from others.
98 */
99 String getName();
100
101 /**
102 * Returns the {@link Channel} whose ID matches the specified integer.
103 *
104 * @return the matching {@link Channel} if found. {@code null} otherwise.
105 */
106 Channel find(Integer id);
107
108 /**
109 * Calls {@link Channel#setInterestOps(int)} for all {@link Channel}s in
110 * this group with the specified {@code interestOps}. Please note that
111 * this operation is asynchronous as {@link Channel#setInterestOps(int)} is.
112 *
113 * @return the {@link ChannelGroupFuture} instance that notifies when
114 * the operation is done for all channels
115 */
116 ChannelGroupFuture setInterestOps(int interestOps);
117
118 /**
119 * Calls {@link Channel#setReadable(boolean)} for all {@link Channel}s in
120 * this group with the specified boolean flag. Please note that this
121 * operation is asynchronous as {@link Channel#setReadable(boolean)} is.
122 *
123 * @return the {@link ChannelGroupFuture} instance that notifies when
124 * the operation is done for all channels
125 */
126 ChannelGroupFuture setReadable(boolean readable);
127
128 /**
129 * Writes the specified {@code message} to all {@link Channel}s in this
130 * group. If the specified {@code message} is an instance of
131 * {@link ChannelBuffer}, it is automatically
132 * {@linkplain ChannelBuffer#duplicate() duplicated} to avoid a race
133 * condition. Please note that this operation is asynchronous as
134 * {@link Channel#write(Object)} is.
135 *
136 * @return the {@link ChannelGroupFuture} instance that notifies when
137 * the operation is done for all channels
138 */
139 ChannelGroupFuture write(Object message);
140
141 /**
142 * Writes the specified {@code message} with the specified
143 * {@code remoteAddress} to all {@link Channel}s in this group. If the
144 * specified {@code message} is an instance of {@link ChannelBuffer}, it is
145 * automatically {@linkplain ChannelBuffer#duplicate() duplicated} to avoid
146 * a race condition. Please note that this operation is asynchronous as
147 * {@link Channel#write(Object, SocketAddress)} is.
148 *
149 * @return the {@link ChannelGroupFuture} instance that notifies when
150 * the operation is done for all channels
151 */
152 ChannelGroupFuture write(Object message, SocketAddress remoteAddress);
153
154 /**
155 * Disconnects all {@link Channel}s in this group from their remote peers.
156 *
157 * @return the {@link ChannelGroupFuture} instance that notifies when
158 * the operation is done for all channels
159 */
160 ChannelGroupFuture disconnect();
161
162 /**
163 * Unbinds all {@link Channel}s in this group from their local address.
164 *
165 * @return the {@link ChannelGroupFuture} instance that notifies when
166 * the operation is done for all channels
167 */
168 ChannelGroupFuture unbind();
169
170 /**
171 * Closes all {@link Channel}s in this group. If the {@link Channel} is
172 * connected to a remote peer or bound to a local address, it is
173 * automatically disconnected and unbound.
174 *
175 * @return the {@link ChannelGroupFuture} instance that notifies when
176 * the operation is done for all channels
177 */
178 ChannelGroupFuture close();
179 }