/* * Copyright 2007-2010 Sun Microsystems, Inc. * * This file is part of Project Darkstar Server. * * Project Darkstar Server is free software: you can redistribute it * and/or modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation and * distributed hereunder to you. * * Project Darkstar Server is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Sun designates this particular file as subject to the "Classpath" * exception as provided by Sun in the LICENSE file that accompanied * this code. * * -- */ package com.sun.sgs.app; import java.io.Serializable; import java.nio.ByteBuffer; import java.util.Iterator; import java.util.Set; /** * Interface representing a communication group, a {@code Channel}, * consisting of multiple client sessions. Classes that implement * {@code Channel} must also implement {@link Serializable}. * * <p>A channel is created by invoking the {@link * ChannelManager#createChannel ChannelManager.createChannel} method with a * name, a {@code ChannelListener}, and a {@link Delivery} guarantee. A * {@link ClientSession} can be added or removed from a channel using that * {@code Channel}'s {@link #join(ClientSession) join} and {@link * #leave(ClientSession) leave} methods respectively. All client sessions * can be removed from a channel by invoking {@link #leaveAll leaveAll} on * the channel. To explicitly close a {@code Channel}, remove the {@code * Channel} object from the data manager using the {@link * DataManager#removeObject DataManager.removeObject} method. * * <p>The server can send a message to all client sessions joined to a * channel by using the {@link #send send} method. Note that the methods * of this interface are invoked within the context of an executing {@link * Task}; as a result, a message sent to client sessions using the {@code * send} method will not be sent until after its corresponding task * completes. * * <p>Messages sent on a channel are delivered in a manner that satisfies * the channel's delivery guarantee, specified at creation time. When * possible, channel messages are delivered using the most efficient means * to satisfy the delivery guarantee. However, a stronger delivery * guarantee may be used to deliver the message if the underlying protocol * only supports stronger delivery guarantees. A client session can not be * joined to a channel if that client session does not support a protocol * satisfying the minimum requirements of the channel's delivery guarantee. * * <p>A client session joined to one or more channels may become * disconnected due to the client logging out or due to other factors * such as forced disconnection or network failure. If a client * session becomes disconnected, then that client session is removed * from each channel that it is a member of. * * <p>When the application is finished using a channel, the * application should remove the channel from the data manager, which * closes the channel and releases all resources associated with the * channel. * * @see ChannelManager#createChannel ChannelManager.createChannel */ public interface Channel extends ManagedObject { /** * Returns the name bound to this channel. * * @return the name bound to this channel * * @throws IllegalStateException if this channel is closed * @throws TransactionException if the operation failed because of * a problem with the current transaction */ String getName(); /** * Returns the delivery guarantee of this channel. * * @return the delivery guarantee * * @throws IllegalStateException if this channel is closed * @throws TransactionException if the operation failed because of * a problem with the current transaction */ Delivery getDelivery(); /** * Returns {@code true} if this channel has client sessions * joined to it, otherwise returns {@code false}. * * <p>The returned result may not reflect changes to the membership * that occurred in the current transaction. Such membership changes * may be handled asynchronously, after the task making the changes * completes. * * @return {@code true} if this channel has sessions joined * to it, otherwise returns {@code false} * * @throws IllegalStateException if this channel is closed * @throws TransactionException if the operation failed because of * a problem with the current transaction */ boolean hasSessions(); /** * Returns an iterator for the client sessions joined to * this channel. The returned iterator may only be used in the task * that this method was invoked from. * * <p>The returned iterator may not reflect recent changes (in the * current transaction or another recent transaction) to the channel's * membership. Membership changes may be handled asynchronously, after * the task making the changes completes. Therefore, the iterator * <i>may not</i> include sessions that have been recently joined to * the channel, or <i>may</i> include sessions that have recently left * the channel (by being explicitly removed from the channel, or by * being disconnected). * * <p>Note: This operation may be expensive, so it should be used * judiciously. * * @return an iterator for the sessions joined to this channel * * @throws IllegalStateException if this channel is closed * @throws TransactionException if the operation failed because of * a problem with the current transaction */ Iterator<ClientSession> getSessions(); /** * Adds a client session to this channel. If the specified * session is already joined to this channel, then no action is * taken. If the client session does not support a protocol that * satisfies the minimum requirements of the channel's delivery * guarantee, then {@code DeliveryNotSupportedException} will be * thrown. * * @param session a client session * * @return this channel * * @throws IllegalStateException if this channel is closed * @throws DeliveryNotSupportedException if the session does not support * the minimum requirements of this channel's delivery guarantee * @throws ResourceUnavailableException if there are not enough resources * to join the channel * @throws TransactionException if the operation failed because of * a problem with the current transaction */ Channel join(ClientSession session); /** * Adds the specified client sessions to this channel. If any client * session in the specified set does not support a protocol that * satisfies the minimum requirements of the channel's delivery * guarantee, then {@code DeliveryNotSupportedException} will be * thrown. * * @param sessions a set of client sessions * * @return this channel * * @throws IllegalStateException if this channel is closed * @throws DeliveryNotSupportedException if any session does not support * the minimum requirements of this channel's delivery guarantee * @throws ResourceUnavailableException if there are not enough resources * to join the channel * @throws TransactionException if the operation failed because of * a problem with the current transaction */ Channel join(Set<? extends ClientSession> sessions); /** * Removes a client session from this channel. If the specified * session is not joined to this channel, then no action is taken. * * @param session a client session * * @return this channel * * @throws IllegalStateException if this channel is closed * @throws TransactionException if the operation failed because of * a problem with the current transaction */ Channel leave(ClientSession session); /** * Removes the specified client sessions from this channel, If a * session in the specified set is not joined to this channel, * then no action for that session is taken. * * @param sessions a set of client sessions * * @return this channel * * @throws IllegalStateException if this channel is closed * @throws TransactionException if the operation failed because of * a problem with the current transaction */ Channel leave(Set<? extends ClientSession> sessions); /** * Removes all client sessions from this channel. * * @return this channel * * @throws IllegalStateException if this channel is closed * @throws TransactionException if the operation failed because of * a problem with the current transaction */ Channel leaveAll(); /** * Sends the message contained in the specified buffer to all client * sessions joined to this channel. The message starts at the buffer's * current position and ends at the buffer's limit. The buffer's * position is not modified by this operation. * * <p>The {@code ByteBuffer} may be reused immediately after this method * returns. Changes made to the buffer after this method returns will * have no effect on the message sent to the channel by this invocation. * * <p>The maximum length of a message that can be sent over the channel is * dependent on the maximum message length supported by all joined client * sessions. (See: {@link ClientSession#getMaxMessageLength}) * * @param message a message * * @return this channel * * @throws IllegalStateException if this channel is closed * @throws IllegalArgumentException if the channel would be unable * to send the specified message because it exceeds a size limit * @throws MessageRejectedException if there are not enough resources * to send the specified message * @throws TransactionException if the operation failed because of * a problem with the current transaction */ Channel send(ByteBuffer message); /** * Sends the message contained in the specified buffer to all client * sessions joined to this channel. The message starts at the buffer's * current position and ends at the buffer's limit. The buffer's * position is not modified by this operation. * * <p>This {@code send} method, which has a {@code sender} argument, is * used to forward a message to a channel from the channel's {@link * ChannelListener}. When the channel's listener receives a message * via its {@link ChannelListener#receivedMessage receivedMessage} * method, the listener can perform access control operations on the * sender, alter the message content, and/or perform other operations * before (optionally) using this method, specifying the given {@code * sender}, to forward the message to the channel. * * <p>If {@code sender} specified to this method is non-{@code null}, * it must be the {@code sender} supplied to the {@code * ChannelListener}'s {@code receivedMessage} method. If that sender * is not a member of this channel when the message is processed to be * sent, then the message will not be forwarded to the channel for * delivery. If the {@code sender} specified to this method is * non-{@code null} and is not the {@code sender} supplied to the * {@code ChannelListener}, then the channel message may not get * delivered to the channel. * * <p>If the {@code sender} is {@code null}, the message will be * forwarded to the channel. * * <p>The {@code ByteBuffer} may be reused immediately after this method * returns. Changes made to the buffer after this method returns will * have no effect on the message sent to the channel by this invocation. * * <p>The maximum length of a message that can be sent over the channel is * dependent on the maximum message length supported by all joined client * sessions. See {@link ClientSession#getMaxMessageLength}. * * @param sender the sending client session, or {@code null} * @param message a message * * @return this channel * * @throws IllegalStateException if this channel is closed * @throws IllegalArgumentException if the channel would be unable * to send the specified message because it exceeds a size limit * @throws MessageRejectedException if there are not enough resources * to send the specified message * @throws TransactionException if the operation failed because of * a problem with the current transaction */ Channel send(ClientSession sender, ByteBuffer message); }