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.common;
21  
22  import java.net.SocketAddress;
23  import java.util.Set;
24  
25  /**
26   * A handle which represents connection between two end-points regardless of
27   * transport types.
28   * <p/>
29   * {@link IoSession} provides user-defined attributes.  User-defined attributes
30   * are application-specific data which is associated with a session.
31   * It often contains objects that represents the state of a higher-level protocol
32   * and becomes a way to exchange data between filters and handlers.
33   * <p/>
34   * <h3>Adjusting Transport Type Specific Properties</h3>
35   * <p/>
36   * You can simply downcast the session to an appropriate subclass.
37   * </p>
38   * <p/>
39   * <h3>Thread Safety</h3>
40   * <p/>
41   * {@link IoSession} is thread-safe.  But please note that performing
42   * more than one {@link #write(Object)} calls at the same time will
43   * cause the {@link IoFilter#filterWrite(IoFilter.NextFilter,IoSession,WriteRequest)}
44   * is executed simultaneously, and therefore you have to make sure the
45   * {@link IoFilter} implementations you're using are thread-safe, too.
46   * </p>
47   * <p/>
48   * <h3>Equality of Sessions</h3>
49   * {@link #equals(Object)} and {@link #hashCode()} shall not be overriden
50   * to the default behavior that is defined in {@link Object}.
51   *
52   * @author The Apache MINA Project (dev@mina.apache.org)
53   * @version $Rev: 601679 $, $Date: 2007-12-06 03:13:21 -0700 (Thu, 06 Dec 2007) $
54   */
55  public interface IoSession {
56  
57      /**
58       * Returns a unique identifier of this session.  Every session has its own
59       * ID which is different from each other.
60       */
61      long getId();
62      
63      /**
64       * Returns the {@link IoService} which provides I/O service to this session.
65       */
66      IoService getService();
67  
68      /**
69       * Returns the {@link IoHandler} which handles this session.
70       */
71      IoHandler getHandler();
72  
73      /**
74       * Returns the configuration of this session.
75       */
76      IoSessionConfig getConfig();
77  
78      /**
79       * Returns the filter chain that only affects this session.
80       */
81      IoFilterChain getFilterChain();
82  
83      /**
84       * Returns the {@link TransportMetadata} that this session runs on.
85       */
86      TransportMetadata getTransportMetadata();
87      
88      /**
89       * Returns a {@link ReadFuture} which is notified when a new message is
90       * received, the connection is closed or an exception is caught.  This
91       * operation is especially useful when you implement a client application.
92       * However, please note that this operation is disabled by default and
93       * throw {@link IllegalStateException} because all received events must be
94       * queued somewhere to support this operation, possibly leading to memory
95       * leak.  This means you have to keep calling {@link #read()} once you
96       * enabled this operation.  To enable this operation, please call
97       * {@link IoSessionConfig#setUseReadOperation(boolean)} with <tt>true</tt>. 
98       * 
99       * @throws IllegalStateException if
100      * {@link IoSessionConfig#setUseReadOperation(boolean) useReadOperation}
101      * option has not been enabled.
102      */
103     ReadFuture read();
104 
105     /**
106      * Writes the specified <code>message</code> to remote peer.  This
107      * operation is asynchronous; {@link IoHandler#messageSent(IoSession,Object)}
108      * will be invoked when the message is actually sent to remote peer.
109      * You can also wait for the returned {@link WriteFuture} if you want
110      * to wait for the message actually written.
111      */
112     WriteFuture write(Object message);
113 
114     /**
115      * (Optional) Writes the specified <tt>message</tt> to the specified <tt>destination</tt>.
116      * This operation is asynchronous; {@link IoHandler#messageSent(IoSession, Object)}
117      * will be invoked when the message is actually sent to remote peer. You can
118      * also wait for the returned {@link WriteFuture} if you want to wait for
119      * the message actually written.
120      * <p>
121      * When you implement a client that receives a broadcast message from a server
122      * such as DHCP server, the client might need to send a response message for the
123      * broadcast message the server sent.  Because the remote address of the session
124      * is not the address of the server in case of broadcasting, there should be a
125      * way to specify the destination when you write the response message.
126      * This interface provides {@link #write(Object, SocketAddress)} method so you
127      * can specify the destination.
128      *
129      * @param destination <tt>null</tt> if you want the message sent to the
130      *                    default remote address
131      *
132      * @throws UnsupportedOperationException if this operation is not supported
133      */
134     WriteFuture write(Object message, SocketAddress destination);
135 
136     /**
137      * Closes this session immediately.  This operation is asynchronous.
138      * Wait for the returned {@link CloseFuture} if you want to wait for
139      * the session actually closed.
140      */
141     CloseFuture close();
142 
143     /**
144      * Closes this session after all queued write requests are flushed.
145      * This operation is asynchronous.  Wait for the returned {@link CloseFuture}
146      * if you want to wait for the session actually closed.
147      */
148     CloseFuture closeOnFlush();
149 
150     /**
151      * Closes this session immediately or after all queued write requests
152      * are flushed.  This operation is asynchronous.  Wait for the returned
153      * {@link CloseFuture} if you want to wait for the session actually closed.
154      *
155      * @param immediately {@code true} to close this session immediately
156      *                    (i.e. {@link #close()}).
157      *                    {@code false} to close this session after all queued
158      *                    write requests are flushed (i.e. {@link #closeOnFlush()}).
159      */
160     CloseFuture close(boolean immediately);
161 
162     /**
163      * Returns an attachment of this session.
164      * This method is identical with <tt>getAttribute( "" )</tt>.
165      * 
166      * @deprecated Use {@link #getAttribute(Object)} instead.
167      */
168     @Deprecated Object getAttachment();
169 
170     /**
171      * Sets an attachment of this session.
172      * This method is identical with <tt>setAttribute( "", attachment )</tt>.
173      *
174      * @return Old attachment.  <tt>null</tt> if it is new.
175      * @deprecated Use {@link #setAttribute(Object, Object)} instead.
176      */
177     @Deprecated Object setAttachment(Object attachment);
178 
179     /**
180      * Returns the value of the user-defined attribute of this session.
181      *
182      * @param key the key of the attribute
183      * @return <tt>null</tt> if there is no attribute with the specified key
184      */
185     Object getAttribute(Object key);
186 
187     /**
188      * Returns the value of user defined attribute associated with the
189      * specified key.  If there's no such attribute, the specified default
190      * value is associated with the specified key, and the default value is
191      * returned.  This method is same with the following code except that the
192      * operation is performed atomically.
193      * <pre>
194      * if (containsAttribute(key)) {
195      *     return getAttribute(key);
196      * } else {
197      *     setAttribute(key, defaultValue);
198      *     return defaultValue;
199      * }
200      * </pre>
201      */
202     Object getAttribute(Object key, Object defaultValue);
203 
204     /**
205      * Sets a user-defined attribute.
206      *
207      * @param key   the key of the attribute
208      * @param value the value of the attribute
209      * @return The old value of the attribute.  <tt>null</tt> if it is new.
210      */
211     Object setAttribute(Object key, Object value);
212 
213     /**
214      * Sets a user defined attribute without a value.  This is useful when
215      * you just want to put a 'mark' attribute.  Its value is set to
216      * {@link Boolean#TRUE}.
217      *
218      * @param key the key of the attribute
219      * @return The old value of the attribute.  <tt>null</tt> if it is new.
220      */
221     Object setAttribute(Object key);
222 
223     /**
224      * Sets a user defined attribute if the attribute with the specified key
225      * is not set yet.  This method is same with the following code except
226      * that the operation is performed atomically.
227      * <pre>
228      * if (containsAttribute(key)) {
229      *     return getAttribute(key);
230      * } else {
231      *     return setAttribute(key, value);
232      * }
233      * </pre>
234      */
235     Object setAttributeIfAbsent(Object key, Object value);
236 
237     /**
238      * Sets a user defined attribute without a value if the attribute with
239      * the specified key is not set yet.  This is useful when you just want to
240      * put a 'mark' attribute.  Its value is set to {@link Boolean#TRUE}.
241      * This method is same with the following code except that the operation
242      * is performed atomically.
243      * <pre>
244      * if (containsAttribute(key)) {
245      *     return getAttribute(key);  // might not always be Boolean.TRUE.
246      * } else {
247      *     return setAttribute(key);
248      * }
249      * </pre>
250      */
251     Object setAttributeIfAbsent(Object key);
252 
253     /**
254      * Removes a user-defined attribute with the specified key.
255      *
256      * @return The old value of the attribute.  <tt>null</tt> if not found.
257      */
258     Object removeAttribute(Object key);
259 
260     /**
261      * Removes a user defined attribute with the specified key if the current
262      * attribute value is equal to the specified value.  This method is same
263      * with the following code except that the operation is performed
264      * atomically.
265      * <pre>
266      * if (containsAttribute(key) && getAttribute(key).equals(value)) {
267      *     removeAttribute(key);
268      *     return true;
269      * } else {
270      *     return false;
271      * }
272      * </pre>
273      */
274     boolean removeAttribute(Object key, Object value);
275 
276     /**
277      * Replaces a user defined attribute with the specified key if the
278      * value of the attribute is equals to the specified old value.
279      * This method is same with the following code except that the operation
280      * is performed atomically.
281      * <pre>
282      * if (containsAttribute(key) && getAttribute(key).equals(oldValue)) {
283      *     setAttribute(key, newValue);
284      *     return true;
285      * } else {
286      *     return false;
287      * }
288      * </pre>
289      */
290     boolean replaceAttribute(Object key, Object oldValue, Object newValue);
291 
292     /**
293      * Returns <tt>true</tt> if this session contains the attribute with
294      * the specified <tt>key</tt>.
295      */
296     boolean containsAttribute(Object key);
297 
298     /**
299      * Returns the set of keys of all user-defined attributes.
300      */
301     Set<Object> getAttributeKeys();
302 
303     /**
304      * Returns <code>true</code> if this session is connected with remote peer.
305      */
306     boolean isConnected();
307 
308     /**
309      * Returns <code>true</tt> if and only if this session is being closed
310      * (but not disconnected yet) or is closed.
311      */
312     boolean isClosing();
313 
314     /**
315      * Returns the {@link CloseFuture} of this session.  This method returns
316      * the same instance whenever user calls it.
317      */
318     CloseFuture getCloseFuture();
319 
320     /**
321      * Returns the socket address of remote peer.
322      */
323     SocketAddress getRemoteAddress();
324 
325     /**
326      * Returns the socket address of local machine which is associated with this
327      * session.
328      */
329     SocketAddress getLocalAddress();
330 
331     /**
332      * Returns the socket address of the {@link IoService} listens to to manage
333      * this session.  If this session is managed by {@link IoAcceptor}, it
334      * returns the {@link SocketAddress} which is specified as a parameter of
335      * {@link IoAcceptor#bind()}.  If this session is managed by
336      * {@link IoConnector}, this method returns the same address with
337      * that of {@link #getRemoteAddress()}.
338      */
339     SocketAddress getServiceAddress();
340 
341     /**
342      * Returns the current {@link TrafficMask} of this session.
343      */
344     TrafficMask getTrafficMask();
345 
346     /**
347      * Sets the {@link TrafficMask} of this session which will result
348      * the parent {@link IoService} to start to control the traffic
349      * of this session immediately.
350      */
351     void setTrafficMask(TrafficMask trafficMask);
352 
353     /**
354      * A shortcut method for {@link #setTrafficMask(TrafficMask)} that
355      * suspends read operations for this session.
356      */
357     void suspendRead();
358 
359     /**
360      * A shortcut method for {@link #setTrafficMask(TrafficMask)} that
361      * suspends write operations for this session.
362      */
363     void suspendWrite();
364 
365     /**
366      * A shortcut method for {@link #setTrafficMask(TrafficMask)} that
367      * resumes read operations for this session.
368      */
369     void resumeRead();
370 
371     /**
372      * A shortcut method for {@link #setTrafficMask(TrafficMask)} that
373      * resumes write operations for this session.
374      */
375     void resumeWrite();
376 
377     /**
378      * Returns the total number of bytes which were read from this session.
379      */
380     long getReadBytes();
381 
382     /**
383      * Returns the total number of bytes which were written to this session.
384      */
385     long getWrittenBytes();
386 
387     /**
388      * Returns the total number of messages which were read and decoded from this session.
389      */
390     long getReadMessages();
391 
392     /**
393      * Returns the total number of messages which were written and encoded by this session.
394      */
395     long getWrittenMessages();
396 
397     /**
398      * Returns the number of read bytes per second.
399      */
400     double getReadBytesThroughput();
401 
402     /**
403      * Returns the number of written bytes per second.
404      */
405     double getWrittenBytesThroughput();
406     
407     /**
408      * Returns the number of read messages per second.
409      */
410     double getReadMessagesThroughput();
411     
412     /**
413      * Returns the number of written messages per second.
414      */
415     double getWrittenMessagesThroughput();
416     
417     /**
418      * Returns the number of messages which are scheduled to be written to this session.
419      */
420     int getScheduledWriteMessages();
421 
422     /**
423      * Returns the number of bytes which are scheduled to be written to this
424      * session.
425      */
426     long getScheduledWriteBytes();
427 
428     /**
429      * Returns the time in millis when this session is created.
430      */
431     long getCreationTime();
432 
433     /**
434      * Returns the time in millis when I/O occurred lastly.
435      */
436     long getLastIoTime();
437 
438     /**
439      * Returns the time in millis when read operation occurred lastly.
440      */
441     long getLastReadTime();
442 
443     /**
444      * Returns the time in millis when write operation occurred lastly.
445      */
446     long getLastWriteTime();
447 
448     /**
449      * Returns <code>true</code> if this session is idle for the specified
450      * {@link IdleStatus}.
451      */
452     boolean isIdle(IdleStatus status);
453 
454     /**
455      * Returns the number of the fired continuous <tt>sessionIdle</tt> events
456      * for the specified {@link IdleStatus}.
457      * <p/>
458      * If <tt>sessionIdle</tt> event is fired first after some time after I/O,
459      * <tt>idleCount</tt> becomes <tt>1</tt>.  <tt>idleCount</tt> resets to
460      * <tt>0</tt> if any I/O occurs again, otherwise it increases to
461      * <tt>2</tt> and so on if <tt>sessionIdle</tt> event is fired again without
462      * any I/O between two (or more) <tt>sessionIdle</tt> events.
463      */
464     int getIdleCount(IdleStatus status);
465 
466     /**
467      * Returns the number of the fired continuous <tt>sessionIdle</tt> events
468      * for {@link IdleStatus#READER_IDLE}.
469      * @see #getIdleCount(IdleStatus)
470      */
471     int getReaderIdleCount();
472 
473     /**
474      * Returns the number of the fired continuous <tt>sessionIdle</tt> events
475      * for {@link IdleStatus#WRITER_IDLE}.
476      * @see #getIdleCount(IdleStatus)
477      */
478     int getWriterIdleCount();
479     
480     /**
481      * Returns the number of the fired continuous <tt>sessionIdle</tt> events
482      * for {@link IdleStatus#BOTH_IDLE}.
483      * @see #getIdleCount(IdleStatus)
484      */
485     int getBothIdleCount();
486     
487     /**
488      * Returns the time in milliseconds when the last <tt>sessionIdle</tt> event
489      * is fired for the specified {@link IdleStatus}.
490      */
491     long getLastIdleTime(IdleStatus status);
492     
493 
494     /**
495      * Returns the time in milliseconds when the last <tt>sessionIdle</tt> event
496      * is fired for {@link IdleStatus#READER_IDLE}.
497      * @see #getLastIdleTime(IdleStatus)
498      */
499     long getLastReaderIdleTime();
500     
501     /**
502      * Returns the time in milliseconds when the last <tt>sessionIdle</tt> event
503      * is fired for {@link IdleStatus#WRITER_IDLE}.
504      * @see #getLastIdleTime(IdleStatus)
505      */
506     long getLastWriterIdleTime();
507     
508     /**
509      * Returns the time in milliseconds when the last <tt>sessionIdle</tt> event
510      * is fired for {@link IdleStatus#BOTH_IDLE}.
511      * @see #getLastIdleTime(IdleStatus)
512      */
513     long getLastBothIdleTime();
514 }