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.transport.socket.nio;
21  
22  import java.net.SocketAddress;
23  import java.net.SocketException;
24  import java.nio.channels.SelectionKey;
25  import java.nio.channels.SocketChannel;
26  
27  import org.apache.mina.common.IoFilterChain;
28  import org.apache.mina.common.IoHandler;
29  import org.apache.mina.common.IoService;
30  import org.apache.mina.common.IoServiceConfig;
31  import org.apache.mina.common.IoSession;
32  import org.apache.mina.common.IoSessionConfig;
33  import org.apache.mina.common.RuntimeIOException;
34  import org.apache.mina.common.TransportType;
35  import org.apache.mina.common.IoFilter.WriteRequest;
36  import org.apache.mina.common.support.BaseIoSession;
37  import org.apache.mina.common.support.BaseIoSessionConfig;
38  import org.apache.mina.common.support.IoServiceListenerSupport;
39  import org.apache.mina.util.Queue;
40  
41  /**
42   * An {@link IoSession} for socket transport (TCP/IP).
43   *
44   * @author The Apache Directory Project (mina-dev@directory.apache.org)
45   * @version $Rev: 556539 $, $Date: 2007-07-16 16:48:36 +0900 (월, 16  7월 2007) $
46   */
47  class SocketSessionImpl extends BaseIoSession {
48      private final IoService manager;
49  
50      private final IoServiceConfig serviceConfig;
51  
52      private final SocketSessionConfig config = new SessionConfigImpl();
53  
54      private final SocketIoProcessor ioProcessor;
55  
56      private final SocketFilterChain filterChain;
57  
58      private final SocketChannel ch;
59  
60      private final Queue writeRequestQueue;
61  
62      private final IoHandler handler;
63  
64      private final SocketAddress remoteAddress;
65  
66      private final SocketAddress localAddress;
67  
68      private final SocketAddress serviceAddress;
69  
70      private final IoServiceListenerSupport serviceListeners;
71  
72      private SelectionKey key;
73  
74      private int readBufferSize = 1024;
75  
76      /**
77       * Creates a new instance.
78       */
79      SocketSessionImpl(IoService manager, SocketIoProcessor ioProcessor,
80              IoServiceListenerSupport listeners, IoServiceConfig serviceConfig,
81              SocketChannel ch, IoHandler defaultHandler,
82              SocketAddress serviceAddress) {
83          this.manager = manager;
84          this.serviceListeners = listeners;
85          this.ioProcessor = ioProcessor;
86          this.filterChain = new SocketFilterChain(this);
87          this.ch = ch;
88          this.writeRequestQueue = new Queue();
89          this.handler = defaultHandler;
90          this.remoteAddress = ch.socket().getRemoteSocketAddress();
91          this.localAddress = ch.socket().getLocalSocketAddress();
92          this.serviceAddress = serviceAddress;
93          this.serviceConfig = serviceConfig;
94  
95          // Apply the initial session settings
96          IoSessionConfig sessionConfig = serviceConfig.getSessionConfig();
97          if (sessionConfig instanceof SocketSessionConfig) {
98              SocketSessionConfig cfg = (SocketSessionConfig) sessionConfig;
99              this.config.setKeepAlive(cfg.isKeepAlive());
100             this.config.setOobInline(cfg.isOobInline());
101             this.config.setReceiveBufferSize(cfg.getReceiveBufferSize());
102             this.config.setReuseAddress(cfg.isReuseAddress());
103             this.config.setSendBufferSize(cfg.getSendBufferSize());
104             this.config.setSoLinger(cfg.getSoLinger());
105             this.config.setTcpNoDelay(cfg.isTcpNoDelay());
106 
107             if (this.config.getTrafficClass() != cfg.getTrafficClass()) {
108                 this.config.setTrafficClass(cfg.getTrafficClass());
109             }
110         }
111     }
112 
113     public IoService getService() {
114         return manager;
115     }
116 
117     public IoServiceConfig getServiceConfig() {
118         return serviceConfig;
119     }
120 
121     public IoSessionConfig getConfig() {
122         return config;
123     }
124 
125     SocketIoProcessor getIoProcessor() {
126         return ioProcessor;
127     }
128 
129     public IoFilterChain getFilterChain() {
130         return filterChain;
131     }
132 
133     SocketChannel getChannel() {
134         return ch;
135     }
136 
137     IoServiceListenerSupport getServiceListeners() {
138         return serviceListeners;
139     }
140 
141     SelectionKey getSelectionKey() {
142         return key;
143     }
144 
145     void setSelectionKey(SelectionKey key) {
146         this.key = key;
147     }
148 
149     public IoHandler getHandler() {
150         return handler;
151     }
152 
153     protected void close0() {
154         filterChain.fireFilterClose(this);
155     }
156 
157     Queue getWriteRequestQueue() {
158         return writeRequestQueue;
159     }
160 
161     public int getScheduledWriteRequests() {
162         synchronized (writeRequestQueue) {
163             return writeRequestQueue.size();
164         }
165     }
166 
167     public int getScheduledWriteBytes() {
168         synchronized (writeRequestQueue) {
169             return writeRequestQueue.byteSize();
170         }
171     }
172 
173     protected void write0(WriteRequest writeRequest) {
174         filterChain.fireFilterWrite(this, writeRequest);
175     }
176 
177     public TransportType getTransportType() {
178         return TransportType.SOCKET;
179     }
180 
181     public SocketAddress getRemoteAddress() {
182         return remoteAddress;
183     }
184 
185     public SocketAddress getLocalAddress() {
186         return localAddress;
187     }
188 
189     public SocketAddress getServiceAddress() {
190         return serviceAddress;
191     }
192 
193     protected void updateTrafficMask() {
194         this.ioProcessor.updateTrafficMask(this);
195     }
196 
197     int getReadBufferSize() {
198         return readBufferSize;
199     }
200     
201     void setReadBufferSize(int readBufferSize) {
202         this.readBufferSize = readBufferSize;
203     }
204 
205     private class SessionConfigImpl extends BaseIoSessionConfig implements
206             SocketSessionConfig {
207         public boolean isKeepAlive() {
208             try {
209                 return ch.socket().getKeepAlive();
210             } catch (SocketException e) {
211                 throw new RuntimeIOException(e);
212             }
213         }
214 
215         public void setKeepAlive(boolean on) {
216             try {
217                 ch.socket().setKeepAlive(on);
218             } catch (SocketException e) {
219                 throw new RuntimeIOException(e);
220             }
221         }
222 
223         public boolean isOobInline() {
224             try {
225                 return ch.socket().getOOBInline();
226             } catch (SocketException e) {
227                 throw new RuntimeIOException(e);
228             }
229         }
230 
231         public void setOobInline(boolean on) {
232             try {
233                 ch.socket().setOOBInline(on);
234             } catch (SocketException e) {
235                 throw new RuntimeIOException(e);
236             }
237         }
238 
239         public boolean isReuseAddress() {
240             try {
241                 return ch.socket().getReuseAddress();
242             } catch (SocketException e) {
243                 throw new RuntimeIOException(e);
244             }
245         }
246 
247         public void setReuseAddress(boolean on) {
248             try {
249                 ch.socket().setReuseAddress(on);
250             } catch (SocketException e) {
251                 throw new RuntimeIOException(e);
252             }
253         }
254 
255         public int getSoLinger() {
256             try {
257                 return ch.socket().getSoLinger();
258             } catch (SocketException e) {
259                 throw new RuntimeIOException(e);
260             }
261         }
262 
263         public void setSoLinger(int linger) {
264             try {
265                 if (linger < 0) {
266                     ch.socket().setSoLinger(false, 0);
267                 } else {
268                     ch.socket().setSoLinger(true, linger);
269                 }
270             } catch (SocketException e) {
271                 throw new RuntimeIOException(e);
272             }
273         }
274 
275         public boolean isTcpNoDelay() {
276             try {
277                 return ch.socket().getTcpNoDelay();
278             } catch (SocketException e) {
279                 throw new RuntimeIOException(e);
280             }
281         }
282 
283         public void setTcpNoDelay(boolean on) {
284             try {
285                 ch.socket().setTcpNoDelay(on);
286             } catch (SocketException e) {
287                 throw new RuntimeIOException(e);
288             }
289         }
290 
291         public int getTrafficClass() {
292             if (SocketSessionConfigImpl.isGetTrafficClassAvailable()) {
293                 try {
294                     return ch.socket().getTrafficClass();
295                 } catch (SocketException e) {
296                     // Throw an exception only when setTrafficClass is also available.
297                     if (SocketSessionConfigImpl.isSetTrafficClassAvailable()) {
298                         throw new RuntimeIOException(e);
299                     }
300                 }
301             }
302 
303             return 0;
304         }
305 
306         public void setTrafficClass(int tc) {
307             if (SocketSessionConfigImpl.isSetTrafficClassAvailable()) {
308                 try {
309                     ch.socket().setTrafficClass(tc);
310                 } catch (SocketException e) {
311                     throw new RuntimeIOException(e);
312                 }
313             }
314         }
315 
316         public int getSendBufferSize() {
317             try {
318                 return ch.socket().getSendBufferSize();
319             } catch (SocketException e) {
320                 throw new RuntimeIOException(e);
321             }
322         }
323 
324         public void setSendBufferSize(int size) {
325             if (SocketSessionConfigImpl.isSetSendBufferSizeAvailable()) {
326                 try {
327                     ch.socket().setSendBufferSize(size);
328                 } catch (SocketException e) {
329                     throw new RuntimeIOException(e);
330                 }
331             }
332         }
333 
334         public int getReceiveBufferSize() {
335             try {
336                 return ch.socket().getReceiveBufferSize();
337             } catch (SocketException e) {
338                 throw new RuntimeIOException(e);
339             }
340         }
341 
342         public void setReceiveBufferSize(int size) {
343             if (SocketSessionConfigImpl.isSetReceiveBufferSizeAvailable()) {
344                 try {
345                     ch.socket().setReceiveBufferSize(size);
346                 } catch (SocketException e) {
347                     throw new RuntimeIOException(e);
348                 }
349             }
350         }
351     }
352 }