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 }