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 }