1 /* 2 * Copyright 2009 Red Hat, Inc. 3 * 4 * Red Hat licenses this file to you under the Apache License, version 2.0 5 * (the "License"); you may not use this file except in compliance with the 6 * 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 * 91 * @author <a href="http://www.jboss.org/netty/">The Netty Project</a> 92 * @author <a href="http://gleamynode.net/">Trustin Lee</a> 93 * @version $Rev: 2122 $, $Date: 2010-02-02 11:00:04 +0900 (Tue, 02 Feb 2010) $ 94 * 95 * @apiviz.landmark 96 * @apiviz.has org.jboss.netty.channel.group.ChannelGroupFuture oneway - - returns 97 */ 98 public interface ChannelGroup extends Set<Channel>, Comparable<ChannelGroup> { 99 100 /** 101 * Returns the name of this group. A group name is purely for helping 102 * you to distinguish one group from others. 103 */ 104 String getName(); 105 106 /** 107 * Returns the {@link Channel} whose ID matches the specified integer. 108 * 109 * @return the matching {@link Channel} if found. {@code null} otherwise. 110 */ 111 Channel find(Integer id); 112 113 /** 114 * Calls {@link Channel#setInterestOps(int)} for all {@link Channel}s in 115 * this group with the specified {@code interestOps}. Please note that 116 * this operation is asynchronous as {@link Channel#setInterestOps(int)} is. 117 * 118 * @return the {@link ChannelGroupFuture} instance that notifies when 119 * the operation is done for all channels 120 */ 121 ChannelGroupFuture setInterestOps(int interestOps); 122 123 /** 124 * Calls {@link Channel#setReadable(boolean)} for all {@link Channel}s in 125 * this group with the specified boolean flag. Please note that this 126 * operation is asynchronous as {@link Channel#setReadable(boolean)} is. 127 * 128 * @return the {@link ChannelGroupFuture} instance that notifies when 129 * the operation is done for all channels 130 */ 131 ChannelGroupFuture setReadable(boolean readable); 132 133 /** 134 * Writes the specified {@code message} to all {@link Channel}s in this 135 * group. If the specified {@code message} is an instance of 136 * {@link ChannelBuffer}, it is automatically 137 * {@linkplain ChannelBuffer#duplicate() duplicated} to avoid a race 138 * condition. Please note that this operation is asynchronous as 139 * {@link Channel#write(Object)} is. 140 * 141 * @return the {@link ChannelGroupFuture} instance that notifies when 142 * the operation is done for all channels 143 */ 144 ChannelGroupFuture write(Object message); 145 146 /** 147 * Writes the specified {@code message} with the specified 148 * {@code remoteAddress} to all {@link Channel}s in this group. If the 149 * specified {@code message} is an instance of {@link ChannelBuffer}, it is 150 * automatically {@linkplain ChannelBuffer#duplicate() duplicated} to avoid 151 * a race condition. Please note that this operation is asynchronous as 152 * {@link Channel#write(Object, SocketAddress)} is. 153 * 154 * @return the {@link ChannelGroupFuture} instance that notifies when 155 * the operation is done for all channels 156 */ 157 ChannelGroupFuture write(Object message, SocketAddress remoteAddress); 158 159 /** 160 * Disconnects all {@link Channel}s in this group from their remote peers. 161 * 162 * @return the {@link ChannelGroupFuture} instance that notifies when 163 * the operation is done for all channels 164 */ 165 ChannelGroupFuture disconnect(); 166 167 /** 168 * Unbinds all {@link Channel}s in this group from their local address. 169 * 170 * @return the {@link ChannelGroupFuture} instance that notifies when 171 * the operation is done for all channels 172 */ 173 ChannelGroupFuture unbind(); 174 175 /** 176 * Closes all {@link Channel}s in this group. If the {@link Channel} is 177 * connected to a remote peer or bound to a local address, it is 178 * automatically disconnected and unbound. 179 * 180 * @return the {@link ChannelGroupFuture} instance that notifies when 181 * the operation is done for all channels 182 */ 183 ChannelGroupFuture close(); 184 }