View Javadoc

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
    10   *    http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   *  Unless required by applicable law or agreed to in writing,
    13   *  software distributed under the License is distributed on an
    14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   *  KIND, either express or implied.  See the License for the
    16   *  specific language governing permissions and limitations
    17   *  under the License.
    18   *
    19   */
    20  package org.apache.mina.core.session;
    21
    22  import java.net.SocketAddress;
    23  import java.util.Set;
    24
    25  import org.apache.mina.core.filterchain.IoFilter;
    26  import org.apache.mina.core.filterchain.IoFilterChain;
    27  import org.apache.mina.core.future.CloseFuture;
    28  import org.apache.mina.core.future.ReadFuture;
    29  import org.apache.mina.core.future.WriteFuture;
    30  import org.apache.mina.core.service.IoAcceptor;
    31  import org.apache.mina.core.service.IoConnector;
    32  import org.apache.mina.core.service.IoHandler;
    33  import org.apache.mina.core.service.IoService;
    34  import org.apache.mina.core.service.TransportMetadata;
    35  import org.apache.mina.core.write.WriteRequest;
    36  import org.apache.mina.core.write.WriteRequestQueue;
    37
    38  /**
    39   * A handle which represents connection between two end-points regardless of
    40   * transport types.
    41   * <p/>
    42   * {@link IoSession} provides user-defined attributes.  User-defined attributes
    43   * are application-specific data which are associated with a session.
    44   * It often contains objects that represents the state of a higher-level protocol
    45   * and becomes a way to exchange data between filters and handlers.
    46   * <p/>
    47   * <h3>Adjusting Transport Type Specific Properties</h3>
    48   * <p/>
    49   * You can simply downcast the session to an appropriate subclass.
    50   * </p>
    51   * <p/>
    52   * <h3>Thread Safety</h3>
    53   * <p/>
    54   * {@link IoSession} is thread-safe.  But please note that performing
    55   * more than one {@link #write(Object)} calls at the same time will
    56   * cause the {@link IoFilter#filterWrite(IoFilter.NextFilter,IoSession,WriteRequest)}
    57   * to be executed simultaneously, and therefore you have to make sure the
    58   * {@link IoFilter} implementations you're using are thread-safe, too.
    59   * </p>
    60   * <p/>
    61   * <h3>Equality of Sessions</h3>
    62   * TODO : The getId() method is totally wrong. We can't base
    63   * a method which is designed to create a unique ID on the hashCode method.
    64   * {@link #equals(Object)} and {@link #hashCode()} shall not be overriden
    65   * to the default behavior that is defined in {@link Object}.
    66   *
    67   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    68   */
    69  public interface IoSession {
    70      /**
    71       * @return a unique identifier for this session.  Every session has its own
    72       * ID which is different from each other.
    73       *
    74       * TODO : The way it's implemented does not guarantee that the contract is
    75       * respected. It uses the HashCode() method which don't guarantee the key
    76       * unicity.
    77       */
    78      long getId();
    79
    80      /**
    81       * @return the {@link IoService} which provides I/O service to this session.
    82       */
    83      IoService getService();
    84
    85      /**
    86       * @return the {@link IoHandler} which handles this session.
    87       */
    88      IoHandler getHandler();
    89
    90      /**
    91       * @return the configuration of this session.
    92       */
    93      IoSessionConfig getConfig();
    94
    95      /**
    96       * @return the filter chain that only affects this session.
    97       */
    98      IoFilterChain getFilterChain();
    99
    100     /**
    101      * TODO Add method documentation
    102      */
    103     WriteRequestQueue getWriteRequestQueue();
    104
    105     /**
    106      * @return the {@link TransportMetadata} that this session runs on.
    107      */
    108     TransportMetadata getTransportMetadata();
    109
    110     /**
    111      * TODO This javadoc is wrong. The return tag should be short.
    112      *
    113      * @return a {@link ReadFuture} which is notified when a new message is
    114      * received, the connection is closed or an exception is caught.  This
    115      * operation is especially useful when you implement a client application.
    116      * TODO : Describe here how we enable this feature.
    117      * However, please note that this operation is disabled by default and
    118      * throw {@link IllegalStateException} because all received events must be
    119      * queued somewhere to support this operation, possibly leading to memory
    120      * leak.  This means you have to keep calling {@link #read()} once you
    121      * enabled this operation.  To enable this operation, please call
    122      * {@link IoSessionConfig#setUseReadOperation(boolean)} with <tt>true</tt>.
    123      *
    124      * @throws IllegalStateException if
    125      * {@link IoSessionConfig#setUseReadOperation(boolean) useReadOperation}
    126      * option has not been enabled.
    127      */
    128     ReadFuture read();
    129
    130     /**
    131      * Writes the specified <code>message</code> to remote peer.  This
    132      * operation is asynchronous; {@link IoHandler#messageSent(IoSession,Object)}
    133      * will be invoked when the message is actually sent to remote peer.
    134      * You can also wait for the returned {@link WriteFuture} if you want
    135      * to wait for the message actually written.
    136      */
    137     WriteFuture write(Object message);
    138
    139     /**
    140      * (Optional) Writes the specified <tt>message</tt> to the specified <tt>destination</tt>.
    141      * This operation is asynchronous; {@link IoHandler#messageSent(IoSession, Object)}
    142      * will be invoked when the message is actually sent to remote peer. You can
    143      * also wait for the returned {@link WriteFuture} if you want to wait for
    144      * the message actually written.
    145      * <p>
    146      * When you implement a client that receives a broadcast message from a server
    147      * such as DHCP server, the client might need to send a response message for the
    148      * broadcast message the server sent.  Because the remote address of the session
    149      * is not the address of the server in case of broadcasting, there should be a
    150      * way to specify the destination when you write the response message.
    151      * This interface provides {@link #write(Object, SocketAddress)} method so you
    152      * can specify the destination.
    153      *
    154      * @param destination <tt>null</tt> if you want the message sent to the
    155      *                    default remote address
    156      *
    157      * @throws UnsupportedOperationException if this operation is not supported
    158      */
    159     WriteFuture write(Object message, SocketAddress destination);
    160
    161     /**
    162      * Closes this session immediately or after all queued write requests
    163      * are flushed.  This operation is asynchronous.  Wait for the returned
    164      * {@link CloseFuture} if you want to wait for the session actually closed.
    165      *
    166      * @param immediately {@code true} to close this session immediately
    167      *                    (i.e. {@link #close()}). The pending write requests
    168      *                    will simply be discarded.
    169      *                    {@code false} to close this session after all queued
    170      *                    write requests are flushed (i.e. {@link #closeOnFlush()}).
    171      */
    172     CloseFuture close(boolean immediately);
    173
    174     /**
    175      * Closes this session after all queued write requests
    176      * are flushed. This operation is asynchronous.  Wait for the returned
    177      * {@link CloseFuture} if you want to wait for the session actually closed.
    178      * @deprecated use {@link IoSession#close(boolean)}
    179      */
    180     @Deprecated
    181     CloseFuture close();
    182
    183     /**
    184      * Returns an attachment of this session.
    185      * This method is identical with <tt>getAttribute( "" )</tt>.
    186      *
    187      * @deprecated Use {@link #getAttribute(Object)} instead.
    188      */
    189     @Deprecated
    190     Object getAttachment();
    191
    192     /**
    193      * Sets an attachment of this session.
    194      * This method is identical with <tt>setAttribute( "", attachment )</tt>.
    195      *
    196      * @return Old attachment.  <tt>null</tt> if it is new.
    197      * @deprecated Use {@link #setAttribute(Object, Object)} instead.
    198      */
    199     @Deprecated
    200     Object setAttachment(Object attachment);
    201
    202     /**
    203      * Returns the value of the user-defined attribute of this session.
    204      *
    205      * @param key the key of the attribute
    206      * @return <tt>null</tt> if there is no attribute with the specified key
    207      */
    208     Object getAttribute(Object key);
    209
    210     /**
    211      * Returns the value of user defined attribute associated with the
    212      * specified key.  If there's no such attribute, the specified default
    213      * value is associated with the specified key, and the default value is
    214      * returned.  This method is same with the following code except that the
    215      * operation is performed atomically.
    216      * <pre>
    217      * if (containsAttribute(key)) {
    218      *     return getAttribute(key);
    219      * } else {
    220      *     setAttribute(key, defaultValue);
    221      *     return defaultValue;
    222      * }
    223      * </pre>
    224      */
    225     Object getAttribute(Object key, Object defaultValue);
    226
    227     /**
    228      * Sets a user-defined attribute.
    229      *
    230      * @param key   the key of the attribute
    231      * @param value the value of the attribute
    232      * @return The old value of the attribute.  <tt>null</tt> if it is new.
    233      */
    234     Object setAttribute(Object key, Object value);
    235
    236     /**
    237      * Sets a user defined attribute without a value.  This is useful when
    238      * you just want to put a 'mark' attribute.  Its value is set to
    239      * {@link Boolean#TRUE}.
    240      *
    241      * @param key the key of the attribute
    242      * @return The old value of the attribute.  <tt>null</tt> if it is new.
    243      */
    244     Object setAttribute(Object key);
    245
    246     /**
    247      * Sets a user defined attribute if the attribute with the specified key
    248      * is not set yet.  This method is same with the following code except
    249      * that the operation is performed atomically.
    250      * <pre>
    251      * if (containsAttribute(key)) {
    252      *     return getAttribute(key);
    253      * } else {
    254      *     return setAttribute(key, value);
    255      * }
    256      * </pre>
    257      */
    258     Object setAttributeIfAbsent(Object key, Object value);
    259
    260     /**
    261      * Sets a user defined attribute without a value if the attribute with
    262      * the specified key is not set yet.  This is useful when you just want to
    263      * put a 'mark' attribute.  Its value is set to {@link Boolean#TRUE}.
    264      * This method is same with the following code except that the operation
    265      * is performed atomically.
    266      * <pre>
    267      * if (containsAttribute(key)) {
    268      *     return getAttribute(key);  // might not always be Boolean.TRUE.
    269      * } else {
    270      *     return setAttribute(key);
    271      * }
    272      * </pre>
    273      */
    274     Object setAttributeIfAbsent(Object key);
    275
    276     /**
    277      * Removes a user-defined attribute with the specified key.
    278      *
    279      * @return The old value of the attribute.  <tt>null</tt> if not found.
    280      */
    281     Object removeAttribute(Object key);
    282
    283     /**
    284      * Removes a user defined attribute with the specified key if the current
    285      * attribute value is equal to the specified value.  This method is same
    286      * with the following code except that the operation is performed
    287      * atomically.
    288      * <pre>
    289      * if (containsAttribute(key) && getAttribute(key).equals(value)) {
    290      *     removeAttribute(key);
    291      *     return true;
    292      * } else {
    293      *     return false;
    294      * }
    295      * </pre>
    296      */
    297     boolean removeAttribute(Object key, Object value);
    298
    299     /**
    300      * Replaces a user defined attribute with the specified key if the
    301      * value of the attribute is equals to the specified old value.
    302      * This method is same with the following code except that the operation
    303      * is performed atomically.
    304      * <pre>
    305      * if (containsAttribute(key) && getAttribute(key).equals(oldValue)) {
    306      *     setAttribute(key, newValue);
    307      *     return true;
    308      * } else {
    309      *     return false;
    310      * }
    311      * </pre>
    312      */
    313     boolean replaceAttribute(Object key, Object oldValue, Object newValue);
    314
    315     /**
    316      * Returns <tt>true</tt> if this session contains the attribute with
    317      * the specified <tt>key</tt>.
    318      */
    319     boolean containsAttribute(Object key);
    320
    321     /**
    322      * Returns the set of keys of all user-defined attributes.
    323      */
    324     Set<Object> getAttributeKeys();
    325
    326     /**
    327      * Returns <code>true</code> if this session is connected with remote peer.
    328      */
    329     boolean isConnected();
    330
    331     /**
    332      * Returns <code>true</tt> if and only if this session is being closed
    333      * (but not disconnected yet) or is closed.
    334      */
    335     boolean isClosing();
    336
    337     /**
    338      * Returns the {@link CloseFuture} of this session.  This method returns
    339      * the same instance whenever user calls it.
    340      */
    341     CloseFuture getCloseFuture();
    342
    343     /**
    344      * Returns the socket address of remote peer.
    345      */
    346     SocketAddress getRemoteAddress();
    347
    348     /**
    349      * Returns the socket address of local machine which is associated with this
    350      * session.
    351      */
    352     SocketAddress getLocalAddress();
    353
    354     /**
    355      * Returns the socket address of the {@link IoService} listens to to manage
    356      * this session.  If this session is managed by {@link IoAcceptor}, it
    357      * returns the {@link SocketAddress} which is specified as a parameter of
    358      * {@link IoAcceptor#bind()}.  If this session is managed by
    359      * {@link IoConnector}, this method returns the same address with
    360      * that of {@link #getRemoteAddress()}.
    361      */
    362     SocketAddress getServiceAddress();
    363
    364     /**
    365      *
    366      * TODO setWriteRequestQueue.
    367      *
    368      * @param writeRequestQueue
    369      */
    370     void setCurrentWriteRequest(WriteRequest currentWriteRequest);
    371
    372     /**
    373      * Suspends read operations for this session.
    374      */
    375     void suspendRead();
    376
    377     /**
    378      * Suspends write operations for this session.
    379      */
    380     void suspendWrite();
    381
    382     /**
    383      * Resumes read operations for this session.
    384      */
    385     void resumeRead();
    386
    387     /**
    388      * Resumes write operations for this session.
    389      */
    390     void resumeWrite();
    391
    392     /**
    393      * Is read operation is suspended for this session.
    394      * @return <code>true</code> if suspended
    395      */
    396     boolean isReadSuspended();
    397
    398     /**
    399      * Is write operation is suspended for this session.
    400      * @return <code>true</code> if suspended
    401      */
    402     boolean isWriteSuspended();
    403
    404     /**
    405      * Update all statistical properties related with throughput assuming
    406      * the specified time is the current time.  By default this method returns
    407      * silently without updating the throughput properties if they were
    408      * calculated already within last
    409      * {@link IoSessionConfig#getThroughputCalculationInterval() calculation interval}.
    410      * If, however, <tt>force</tt> is specified as <tt>true</tt>, this method
    411      * updates the throughput properties immediately.
    412
    413      * @param currentTime the current time in milliseconds
    414      */
    415     void updateThroughput(long currentTime, boolean force);
    416
    417     /**
    418      * Returns the total number of bytes which were read from this session.
    419      */
    420     long getReadBytes();
    421
    422     /**
    423      * Returns the total number of bytes which were written to this session.
    424      */
    425     long getWrittenBytes();
    426
    427     /**
    428      * Returns the total number of messages which were read and decoded from this session.
    429      */
    430     long getReadMessages();
    431
    432     /**
    433      * Returns the total number of messages which were written and encoded by this session.
    434      */
    435     long getWrittenMessages();
    436
    437     /**
    438      * Returns the number of read bytes per second.
    439      */
    440     double getReadBytesThroughput();
    441
    442     /**
    443      * Returns the number of written bytes per second.
    444      */
    445     double getWrittenBytesThroughput();
    446
    447     /**
    448      * Returns the number of read messages per second.
    449      */
    450     double getReadMessagesThroughput();
    451
    452     /**
    453      * Returns the number of written messages per second.
    454      */
    455     double getWrittenMessagesThroughput();
    456
    457     /**
    458      * Returns the number of messages which are scheduled to be written to this session.
    459      */
    460     int getScheduledWriteMessages();
    461
    462     /**
    463      * Returns the number of bytes which are scheduled to be written to this
    464      * session.
    465      */
    466     long getScheduledWriteBytes();
    467
    468     /**
    469      * Returns the message which is being written by {@link IoService}.
    470      * @return <tt>null</tt> if and if only no message is being written
    471      */
    472     Object getCurrentWriteMessage();
    473
    474     /**
    475      * Returns the {@link WriteRequest} which is being processed by
    476      * {@link IoService}.
    477      *
    478      * @return <tt>null</tt> if and if only no message is being written
    479      */
    480     WriteRequest getCurrentWriteRequest();
    481
    482     /**
    483      * @return the session's creation time in milliseconds
    484      */
    485     long getCreationTime();
    486
    487     /**
    488      * Returns the time in millis when I/O occurred lastly.
    489      */
    490     long getLastIoTime();
    491
    492     /**
    493      * Returns the time in millis when read operation occurred lastly.
    494      */
    495     long getLastReadTime();
    496
    497     /**
    498      * Returns the time in millis when write operation occurred lastly.
    499      */
    500     long getLastWriteTime();
    501
    502     /**
    503      * Returns <code>true</code> if this session is idle for the specified
    504      * {@link IdleStatus}.
    505      */
    506     boolean isIdle(IdleStatus status);
    507
    508     /**
    509      * Returns <code>true</code> if this session is {@link IdleStatus#READER_IDLE}.
    510      * @see #isIdle(IdleStatus)
    511      */
    512     boolean isReaderIdle();
    513
    514     /**
    515      * Returns <code>true</code> if this session is {@link IdleStatus#WRITER_IDLE}.
    516      * @see #isIdle(IdleStatus)
    517      */
    518     boolean isWriterIdle();
    519
    520     /**
    521      * Returns <code>true</code> if this session is {@link IdleStatus#BOTH_IDLE}.
    522      * @see #isIdle(IdleStatus)
    523      */
    524     boolean isBothIdle();
    525
    526     /**
    527      * Returns the number of the fired continuous <tt>sessionIdle</tt> events
    528      * for the specified {@link IdleStatus}.
    529      * <p/>
    530      * If <tt>sessionIdle</tt> event is fired first after some time after I/O,
    531      * <tt>idleCount</tt> becomes <tt>1</tt>.  <tt>idleCount</tt> resets to
    532      * <tt>0</tt> if any I/O occurs again, otherwise it increases to
    533      * <tt>2</tt> and so on if <tt>sessionIdle</tt> event is fired again without
    534      * any I/O between two (or more) <tt>sessionIdle</tt> events.
    535      */
    536     int getIdleCount(IdleStatus status);
    537
    538     /**
    539      * Returns the number of the fired continuous <tt>sessionIdle</tt> events
    540      * for {@link IdleStatus#READER_IDLE}.
    541      * @see #getIdleCount(IdleStatus)
    542      */
    543     int getReaderIdleCount();
    544
    545     /**
    546      * Returns the number of the fired continuous <tt>sessionIdle</tt> events
    547      * for {@link IdleStatus#WRITER_IDLE}.
    548      * @see #getIdleCount(IdleStatus)
    549      */
    550     int getWriterIdleCount();
    551
    552     /**
    553      * Returns the number of the fired continuous <tt>sessionIdle</tt> events
    554      * for {@link IdleStatus#BOTH_IDLE}.
    555      * @see #getIdleCount(IdleStatus)
    556      */
    557     int getBothIdleCount();
    558
    559     /**
    560      * Returns the time in milliseconds when the last <tt>sessionIdle</tt> event
    561      * is fired for the specified {@link IdleStatus}.
    562      */
    563     long getLastIdleTime(IdleStatus status);
    564
    565     /**
    566      * Returns the time in milliseconds when the last <tt>sessionIdle</tt> event
    567      * is fired for {@link IdleStatus#READER_IDLE}.
    568      * @see #getLastIdleTime(IdleStatus)
    569      */
    570     long getLastReaderIdleTime();
    571
    572     /**
    573      * Returns the time in milliseconds when the last <tt>sessionIdle</tt> event
    574      * is fired for {@link IdleStatus#WRITER_IDLE}.
    575      * @see #getLastIdleTime(IdleStatus)
    576      */
    577     long getLastWriterIdleTime();
    578
    579     /**
    580      * Returns the time in milliseconds when the last <tt>sessionIdle</tt> event
    581      * is fired for {@link IdleStatus#BOTH_IDLE}.
    582      * @see #getLastIdleTime(IdleStatus)
    583      */
    584     long getLastBothIdleTime();
    585 }