1 /* 2 * Copyright 2013 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.group; 17 18 import io.netty.bootstrap.ServerBootstrap; 19 import io.netty.buffer.ByteBuf; 20 import io.netty.buffer.ByteBufHolder; 21 import io.netty.buffer.Unpooled; 22 import io.netty.channel.Channel; 23 import io.netty.channel.ChannelHandlerContext; 24 import io.netty.channel.ChannelId; 25 import io.netty.channel.ChannelInboundHandlerAdapter; 26 import io.netty.channel.EventLoop; 27 import io.netty.channel.ServerChannel; 28 import io.netty.util.CharsetUtil; 29 import io.netty.util.concurrent.GlobalEventExecutor; 30 31 import java.util.Set; 32 33 /** 34 * A thread-safe {@link Set} that contains open {@link Channel}s and provides 35 * various bulk operations on them. Using {@link ChannelGroup}, you can 36 * categorize {@link Channel}s into a meaningful group (e.g. on a per-service 37 * or per-state basis.) A closed {@link Channel} is automatically removed from 38 * the collection, so that you don't need to worry about the life cycle of the 39 * added {@link Channel}. A {@link Channel} can belong to more than one 40 * {@link ChannelGroup}. 41 * 42 * <h3>Broadcast a message to multiple {@link Channel}s</h3> 43 * <p> 44 * If you need to broadcast a message to more than one {@link Channel}, you can 45 * add the {@link Channel}s associated with the recipients and call {@link ChannelGroup#write(Object)}: 46 * <pre> 47 * <strong>{@link ChannelGroup} recipients = 48 * new {@link DefaultChannelGroup}({@link GlobalEventExecutor}.INSTANCE);</strong> 49 * recipients.add(channelA); 50 * recipients.add(channelB); 51 * .. 52 * <strong>recipients.write({@link Unpooled}.copiedBuffer( 53 * "Service will shut down for maintenance in 5 minutes.", 54 * {@link CharsetUtil}.UTF_8));</strong> 55 * </pre> 56 * 57 * <h3>Simplify shutdown process with {@link ChannelGroup}</h3> 58 * <p> 59 * If both {@link ServerChannel}s and non-{@link ServerChannel}s exist in the 60 * same {@link ChannelGroup}, any requested I/O operations on the group are 61 * performed for the {@link ServerChannel}s first and then for the others. 62 * <p> 63 * This rule is very useful when you shut down a server in one shot: 64 * 65 * <pre> 66 * <strong>{@link ChannelGroup} allChannels = 67 * new {@link DefaultChannelGroup}({@link GlobalEventExecutor}.INSTANCE);</strong> 68 * 69 * public static void main(String[] args) throws Exception { 70 * {@link ServerBootstrap} b = new {@link ServerBootstrap}(..); 71 * ... 72 * b.childHandler(new MyHandler()); 73 * 74 * // Start the server 75 * b.getPipeline().addLast("handler", new MyHandler()); 76 * {@link Channel} serverChannel = b.bind(..).sync(); 77 * <strong>allChannels.add(serverChannel);</strong> 78 * 79 * ... Wait until the shutdown signal reception ... 80 * 81 * // Close the serverChannel and then all accepted connections. 82 * <strong>allChannels.close().awaitUninterruptibly();</strong> 83 * } 84 * 85 * public class MyHandler extends {@link ChannelInboundHandlerAdapter} { 86 * {@code @Override} 87 * public void channelActive({@link ChannelHandlerContext} ctx) { 88 * // closed on shutdown. 89 * <strong>allChannels.add(ctx.channel());</strong> 90 * super.channelActive(ctx); 91 * } 92 * } 93 * </pre> 94 */ 95 public interface ChannelGroup extends Set<Channel>, Comparable<ChannelGroup> { 96 97 /** 98 * Returns the name of this group. A group name is purely for helping 99 * you to distinguish one group from others. 100 */ 101 String name(); 102 103 /** 104 * Returns the {@link Channel} which has the specified {@link ChannelId}. 105 * 106 * @return the matching {@link Channel} if found. {@code null} otherwise. 107 */ 108 Channel find(ChannelId id); 109 110 /** 111 * Writes the specified {@code message} to all {@link Channel}s in this 112 * group. If the specified {@code message} is an instance of 113 * {@link ByteBuf}, it is automatically 114 * {@linkplain ByteBuf#duplicate() duplicated} to avoid a race 115 * condition. The same is true for {@link ByteBufHolder}. Please note that this operation is asynchronous as 116 * {@link Channel#write(Object)} is. 117 * 118 * @return itself 119 */ 120 ChannelGroupFuture write(Object message); 121 122 /** 123 * Writes the specified {@code message} to all {@link Channel}s in this 124 * group that are matched by the given {@link ChannelMatcher}. If the specified {@code message} is an instance of 125 * {@link ByteBuf}, it is automatically 126 * {@linkplain ByteBuf#duplicate() duplicated} to avoid a race 127 * condition. The same is true for {@link ByteBufHolder}. Please note that this operation is asynchronous as 128 * {@link Channel#write(Object)} is. 129 * 130 * @return the {@link ChannelGroupFuture} instance that notifies when 131 * the operation is done for all channels 132 */ 133 ChannelGroupFuture write(Object message, ChannelMatcher matcher); 134 135 /** 136 * Writes the specified {@code message} to all {@link Channel}s in this 137 * group that are matched by the given {@link ChannelMatcher}. If the specified {@code message} is an instance of 138 * {@link ByteBuf}, it is automatically 139 * {@linkplain ByteBuf#duplicate() duplicated} to avoid a race 140 * condition. The same is true for {@link ByteBufHolder}. Please note that this operation is asynchronous as 141 * {@link Channel#write(Object)} is. 142 * 143 * If {@code voidPromise} is {@code true} {@link Channel#voidPromise()} is used for the writes and so the same 144 * restrictions to the returned {@link ChannelGroupFuture} apply as to a void promise. 145 * 146 * @return the {@link ChannelGroupFuture} instance that notifies when 147 * the operation is done for all channels 148 */ 149 ChannelGroupFuture write(Object message, ChannelMatcher matcher, boolean voidPromise); 150 151 /** 152 * Flush all {@link Channel}s in this 153 * group. If the specified {@code messages} are an instance of 154 * {@link ByteBuf}, it is automatically 155 * {@linkplain ByteBuf#duplicate() duplicated} to avoid a race 156 * condition. Please note that this operation is asynchronous as 157 * {@link Channel#write(Object)} is. 158 * 159 * @return the {@link ChannelGroupFuture} instance that notifies when 160 * the operation is done for all channels 161 */ 162 ChannelGroup flush(); 163 164 /** 165 * Flush all {@link Channel}s in this group that are matched by the given {@link ChannelMatcher}. 166 * If the specified {@code messages} are an instance of 167 * {@link ByteBuf}, it is automatically 168 * {@linkplain ByteBuf#duplicate() duplicated} to avoid a race 169 * condition. Please note that this operation is asynchronous as 170 * {@link Channel#write(Object)} is. 171 * 172 * @return the {@link ChannelGroupFuture} instance that notifies when 173 * the operation is done for all channels 174 */ 175 ChannelGroup flush(ChannelMatcher matcher); 176 177 /** 178 * Shortcut for calling {@link #write(Object)} and {@link #flush()}. 179 */ 180 ChannelGroupFuture writeAndFlush(Object message); 181 182 /** 183 * @deprecated Use {@link #writeAndFlush(Object)} instead. 184 */ 185 @Deprecated 186 ChannelGroupFuture flushAndWrite(Object message); 187 188 /** 189 * Shortcut for calling {@link #write(Object)} and {@link #flush()} and only act on 190 * {@link Channel}s that are matched by the {@link ChannelMatcher}. 191 */ 192 ChannelGroupFuture writeAndFlush(Object message, ChannelMatcher matcher); 193 194 /** 195 * Shortcut for calling {@link #write(Object, ChannelMatcher, boolean)} and {@link #flush()} and only act on 196 * {@link Channel}s that are matched by the {@link ChannelMatcher}. 197 */ 198 ChannelGroupFuture writeAndFlush(Object message, ChannelMatcher matcher, boolean voidPromise); 199 200 /** 201 * @deprecated Use {@link #writeAndFlush(Object, ChannelMatcher)} instead. 202 */ 203 @Deprecated 204 ChannelGroupFuture flushAndWrite(Object message, ChannelMatcher matcher); 205 206 /** 207 * Disconnects all {@link Channel}s in this group from their remote peers. 208 * 209 * @return the {@link ChannelGroupFuture} instance that notifies when 210 * the operation is done for all channels 211 */ 212 ChannelGroupFuture disconnect(); 213 214 /** 215 * Disconnects all {@link Channel}s in this group from their remote peers, 216 * that are matched by the given {@link ChannelMatcher}. 217 * 218 * @return the {@link ChannelGroupFuture} instance that notifies when 219 * the operation is done for all channels 220 */ 221 ChannelGroupFuture disconnect(ChannelMatcher matcher); 222 223 /** 224 * Closes all {@link Channel}s in this group. If the {@link Channel} is 225 * connected to a remote peer or bound to a local address, it is 226 * automatically disconnected and unbound. 227 * 228 * @return the {@link ChannelGroupFuture} instance that notifies when 229 * the operation is done for all channels 230 */ 231 ChannelGroupFuture close(); 232 233 /** 234 * Closes all {@link Channel}s in this group that are matched by the given {@link ChannelMatcher}. 235 * If the {@link Channel} is connected to a remote peer or bound to a local address, it is 236 * automatically disconnected and unbound. 237 * 238 * @return the {@link ChannelGroupFuture} instance that notifies when 239 * the operation is done for all channels 240 */ 241 ChannelGroupFuture close(ChannelMatcher matcher); 242 243 /** 244 * @deprecated This method will be removed in the next major feature release. 245 * 246 * Deregister all {@link Channel}s in this group from their {@link EventLoop}. 247 * Please note that this operation is asynchronous as {@link Channel#deregister()} is. 248 * 249 * @return the {@link ChannelGroupFuture} instance that notifies when 250 * the operation is done for all channels 251 */ 252 @Deprecated 253 ChannelGroupFuture deregister(); 254 255 /** 256 * @deprecated This method will be removed in the next major feature release. 257 * 258 * Deregister all {@link Channel}s in this group from their {@link EventLoop} that are matched by the given 259 * {@link ChannelMatcher}. Please note that this operation is asynchronous as {@link Channel#deregister()} is. 260 * 261 * @return the {@link ChannelGroupFuture} instance that notifies when 262 * the operation is done for all channels 263 */ 264 @Deprecated 265 ChannelGroupFuture deregister(ChannelMatcher matcher); 266 267 /** 268 * Returns the {@link ChannelGroupFuture} which will be notified when all {@link Channel}s that are part of this 269 * {@link ChannelGroup}, at the time of calling, are closed. 270 */ 271 ChannelGroupFuture newCloseFuture(); 272 273 /** 274 * Returns the {@link ChannelGroupFuture} which will be notified when all {@link Channel}s that are part of this 275 * {@link ChannelGroup}, at the time of calling, are closed. 276 */ 277 ChannelGroupFuture newCloseFuture(ChannelMatcher matcher); 278 }