Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

AbstractServer.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file AbstractServer.d
00004         
00005         Copyright (c) 2004 Kris Bell
00006         
00007         This software is provided 'as-is', without any express or implied
00008         warranty. In no event will the authors be held liable for damages
00009         of any kind arising from the use of this software.
00010         
00011         Permission is hereby granted to anyone to use this software for any 
00012         purpose, including commercial applications, and to alter it and/or 
00013         redistribute it freely, subject to the following restrictions:
00014         
00015         1. The origin of this software must not be misrepresented; you must 
00016            not claim that you wrote the original software. If you use this 
00017            software in a product, an acknowledgment within documentation of 
00018            said product would be appreciated but is not required.
00019 
00020         2. Altered source versions must be plainly marked as such, and must 
00021            not be misrepresented as being the original software.
00022 
00023         3. This notice may not be removed or altered from any distribution
00024            of the source.
00025 
00026         4. Derivative works are permitted, but they must carry this notice
00027            in full and credit the original source.
00028 
00029 
00030                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00031 
00032         
00033         @version        Initial version, April 2004    
00034           
00035         @author         Kris
00036 
00037 
00038 *******************************************************************************/
00039 
00040 module mango.utils.AbstractServer;
00041 
00042 private import  mango.log.Logger;
00043 
00044 private import  mango.io.Exception,
00045                 mango.io.ServerSocket,
00046                 mango.io.SocketConduit;
00047 
00048 private import  mango.convert.Integer;
00049 
00050 private import  mango.io.model.IConduit;
00051 
00052 private import  mango.utils.ServerThread;
00053 
00054 private import  mango.utils.model.IServer;
00055 
00056 
00057 /******************************************************************************
00058 
00059         Exposes the foundation of a multi-threaded Socket server. This is 
00060         subclassed by  mango.http.server.HttpServer, which itself would
00061         likely be subclassed by a SecureHttpServer. 
00062 
00063 ******************************************************************************/
00064 
00065 class AbstractServer : IServer
00066 {
00067         private InternetAddress bind;
00068         private int             threads;
00069         private int             backlog;
00070         private ServerSocket    socket;
00071         private ILogger         logger;
00072 
00073         /**********************************************************************
00074 
00075                 Setup this server with the requisite attributes. The number
00076                 of threads specified dictate exactly that. You might have 
00077                 anything between 1 thread and several hundred, dependent
00078                 upon the underlying O/S and hardware.
00079 
00080                 Parameter 'backlog' specifies the max number of"simultaneous" 
00081                 connection requests to be handled by an underlying socket 
00082                 implementation.
00083 
00084         **********************************************************************/
00085 
00086         this (InternetAddress bind, int threads, int backlog, ILogger logger = null)
00087         in {
00088            assert (bind);
00089            assert (backlog >= 0);
00090            assert (threads > 0 && threads < 1025);
00091            }
00092         body
00093         {
00094                 this.bind = bind;
00095                 this.threads = threads;
00096                 this.backlog = backlog;
00097 
00098                 // save our logger for later reference
00099                 if (logger is null)
00100                     logger = Logger.getLogger ("mango.utils.AbstractServer");
00101                 this.logger = logger;
00102 
00103         }
00104 
00105         /**********************************************************************
00106 
00107                 Concrete server must expose a name 
00108 
00109         **********************************************************************/
00110 
00111         protected abstract char[] toString();
00112 
00113         /**********************************************************************
00114 
00115                 Concrete server must expose a ServerSocket factory
00116 
00117         **********************************************************************/
00118 
00119         protected abstract ServerSocket createSocket (InternetAddress bind, int backlog);
00120 
00121         /**********************************************************************
00122 
00123                 Concrete server must expose a ServerThread factory
00124 
00125         **********************************************************************/
00126 
00127         protected abstract ServerThread createThread (ServerSocket socket);
00128 
00129         /**********************************************************************
00130 
00131                 Concrete server must expose a service handler
00132 
00133         **********************************************************************/
00134 
00135         abstract void service (ServerThread thread, IConduit conduit);
00136 
00137         /**********************************************************************
00138 
00139                 Provide support for figuring out the remote address
00140 
00141         **********************************************************************/
00142 
00143         char[] getRemoteAddress (IConduit conduit)
00144         {
00145                 SocketConduit socket = cast(SocketConduit) conduit;
00146                 InternetAddress addr = cast(InternetAddress) socket.remoteAddress();
00147 
00148                 if (addr)
00149                     return addr.toAddrString();
00150                 return "127.0.0.1";
00151         }
00152 
00153         /**********************************************************************
00154 
00155                 Provide support for figuring out the remote host. Not
00156                 currently implemented.
00157                 
00158         **********************************************************************/
00159 
00160         char[] getRemoteHost (IConduit conduit)
00161         {
00162                 return null;
00163         }
00164 
00165         /**********************************************************************
00166 
00167                 Return the local port we're attached to
00168 
00169         **********************************************************************/
00170 
00171         int getPort ()
00172         {
00173                 InternetAddress addr = cast(InternetAddress) socket.localAddress();
00174                 return addr.port();
00175         }
00176 
00177         /**********************************************************************
00178 
00179                 Return the local address we're attached to
00180 
00181         **********************************************************************/
00182 
00183         char[] getHost ()
00184         {
00185                 InternetAddress addr = cast(InternetAddress) socket.localAddress();
00186                 return addr.toAddrString();
00187         }
00188 
00189         /**********************************************************************
00190 
00191                 Return the logger associated with this server
00192 
00193         **********************************************************************/
00194 
00195         ILogger getLogger ()
00196         {
00197                 return logger;
00198         }
00199 
00200         /**********************************************************************
00201 
00202                 Start this server
00203 
00204         **********************************************************************/
00205 
00206         void start ()
00207         {
00208                 // have the subclass create a ServerSocket for us 
00209                 socket = createSocket (bind, backlog);
00210                 
00211                 // instantiate and start all threads
00212                 for (int i=threads; --i >= 0;)
00213                      createThread (socket).start();
00214 
00215                 char[] info = "Server "~toString()~" started on "~
00216                                socket.localAddress().toString()~
00217                                " with "~Integer.format(new char[5], threads)~" accept threads, "~
00218                                Integer.format(new char[5], backlog)~" backlogs";
00219 
00220                 // indicate what's going on 
00221                 logger.info (info);
00222         }
00223 }

Generated on Sat Dec 24 17:28:31 2005 for Mango by  doxygen 1.4.0