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