View Javadoc

1   /*** 
2    * 
3    * Copyright 2004 Hiram Chirino
4    * 
5    * Licensed under the Apache License, Version 2.0 (the "License"); 
6    * you may not use this file except in compliance with the License. 
7    * You may obtain a copy of the License at 
8    * 
9    * http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, 
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
14   * See the License for the specific language governing permissions and 
15   * limitations under the License. 
16   * 
17   **/
18  package org.activeio.net;
19  
20  import java.io.IOException;
21  import java.net.InetAddress;
22  import java.net.InetSocketAddress;
23  import java.net.URI;
24  import java.net.URISyntaxException;
25  import java.nio.channels.ServerSocketChannel;
26  import java.nio.channels.SocketChannel;
27  
28  import org.activeio.AsynchChannel;
29  import org.activeio.AsynchChannelFactory;
30  import org.activeio.AsynchChannelServer;
31  import org.activeio.adapter.SynchToAsynchChannelServerAdapter;
32  import org.activeio.filter.WriteBufferedAsynchChannel;
33  import org.activeio.packet.ByteBufferPacket;
34  
35  /***
36   * A TcpAsynchChannelFactory creates {@see org.activeio.net.TcpAsynchChannel}
37   * and {@see org.activeio.net.TcpAsynchChannelServer} objects.
38   * 
39   * @version $Revision$
40   */
41  public class NIOAsynchChannelFactory implements AsynchChannelFactory {
42      
43      protected static final int DEFAULT_BUFFER_SIZE = Integer.parseInt(System.getProperty("org.activeio.net.nio.BufferSize", ""+(64*1024)));
44  
45      protected static final int DEFAULT_BACKLOG = 500;
46      boolean useDirectBuffers = true;
47      private final boolean createWriteBufferedChannels;
48      private int backlog = DEFAULT_BACKLOG;
49      
50      public NIOAsynchChannelFactory() {
51          this(true);
52      }
53      
54      public NIOAsynchChannelFactory(boolean createWriteBufferedChannels) {
55          this.createWriteBufferedChannels = createWriteBufferedChannels;
56      }
57      
58      
59      /***
60       * Uses the {@param location}'s host and port to create a tcp connection to a remote host.
61       * 
62       * @see org.activeio.AsynchChannelFactory#openAsynchChannel(java.net.URI)
63       */
64      public AsynchChannel openAsynchChannel(URI location) throws IOException {
65          SocketChannel channel = SocketChannel.open();
66          channel.connect(new InetSocketAddress(location.getHost(), location.getPort()));
67          return createAsynchChannel(channel);
68      }
69  
70      /***
71       * @param channel
72       * @return
73       * @throws IOException
74       */
75      protected AsynchChannel createAsynchChannel(SocketChannel socketChannel) throws IOException {
76          AsynchChannel channel = new NIOAsynchChannel(socketChannel, useDirectBuffers);
77          if( createWriteBufferedChannels ) {
78              channel = new WriteBufferedAsynchChannel(channel, ByteBufferPacket.createDefaultBuffer(useDirectBuffers), false);
79          }
80          return channel;
81      }
82  
83      /***
84       * Binds a server socket a the {@param location}'s port. 
85       * 
86       * @see org.activeio.AsynchChannelFactory#bindAsynchChannel(java.net.URI)
87       */
88      public AsynchChannelServer bindAsynchChannel(URI bindURI) throws IOException {
89          
90          String host = bindURI.getHost();
91          InetSocketAddress address;
92          if ( host == null || host.length() == 0 || host.equals("localhost") || host.equals("0.0.0.0") ) {
93              address = new InetSocketAddress(bindURI.getPort());
94          } else {
95              address = new InetSocketAddress(bindURI.getHost(), bindURI.getPort());
96          }
97          
98          ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
99          serverSocketChannel.socket().bind(address,backlog);
100         
101         URI connectURI = bindURI;
102         try {
103             connectURI = URISupport.changeHost(connectURI, InetAddress.getLocalHost().getHostName());
104             connectURI = URISupport.changePort(connectURI, serverSocketChannel.socket().getLocalPort());
105         } catch (URISyntaxException e) {
106             throw (IOException)new IOException("Could not build connect URI: "+e).initCause(e);
107         }
108         
109         // We won't use non blocking NIO for the server since you only need 1 thread for him anyways.
110         // Just resuing the SocketChannelSynchChannelServer.
111         return SynchToAsynchChannelServerAdapter.adapt( 
112                 new NIOAsynchChannelServer(serverSocketChannel, bindURI, connectURI, createWriteBufferedChannels, useDirectBuffers));
113     }
114     
115     /***
116      * @return Returns the backlog.
117      */
118     public int getBacklog() {
119         return backlog;
120     }
121 
122     /***
123      * @param backlog
124      *            The backlog to set.
125      */
126     public void setBacklog(int backlog) {
127         this.backlog = backlog;
128     }
129 
130 
131 }