132
|
1 /*******************************************************************************
|
|
2
|
|
3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved
|
|
4
|
|
5 license: BSD style: $(LICENSE)
|
|
6
|
|
7 version: Initial release: April 2004
|
|
8
|
|
9 author: Kris
|
|
10
|
|
11 *******************************************************************************/
|
|
12
|
|
13 module tango.net.cluster.tina.util.AbstractServer;
|
|
14
|
|
15 private import tango.net.Socket;
|
|
16
|
|
17 protected import tango.util.log.Log;
|
|
18
|
|
19 protected import tango.net.ServerSocket,
|
|
20 tango.net.SocketConduit;
|
|
21
|
|
22 protected import tango.io.model.IConduit;
|
|
23
|
|
24 protected import tango.text.convert.Sprint;
|
|
25
|
|
26 protected import tango.net.cluster.tina.util.model.IServer;
|
|
27
|
|
28 /******************************************************************************
|
|
29
|
|
30 Exposes the foundation of a multi-threaded Socket server. This is
|
|
31 subclassed by mango.net.http.server.HttpServer, which itself would
|
|
32 likely be subclassed by a SecureHttpServer.
|
|
33
|
|
34 ******************************************************************************/
|
|
35
|
|
36 class AbstractServer : IServer
|
|
37 {
|
|
38 private InternetAddress bind;
|
|
39 private ServerSocket server;
|
|
40 private Logger logger;
|
|
41 private Sprint!(char) sprint;
|
|
42 private uint threads;
|
|
43 private uint backlog;
|
|
44
|
|
45 /**********************************************************************
|
|
46
|
|
47 Setup this server with the requisite attributes. The number
|
|
48 of threads specified dictate exactly that. You might have
|
|
49 anything between 1 thread and several hundred, dependent
|
|
50 upon the underlying O/S and hardware.
|
|
51
|
|
52 Parameter 'backlog' specifies the max number of"simultaneous"
|
|
53 connection requests to be handled by an underlying socket
|
|
54 implementation.
|
|
55
|
|
56 **********************************************************************/
|
|
57
|
|
58 this (InternetAddress bind, int threads, int backlog, Logger logger)
|
|
59 in {
|
|
60 assert (bind);
|
|
61 assert (logger);
|
|
62 assert (backlog >= 0);
|
|
63 assert (threads > 0 && threads < 256);
|
|
64 }
|
|
65 body
|
|
66 {
|
|
67 this.bind = bind;
|
|
68 this.logger = logger;
|
|
69 this.threads = threads;
|
|
70 this.backlog = backlog;
|
|
71 this.sprint = new Sprint!(char);
|
|
72 }
|
|
73
|
|
74 /**********************************************************************
|
|
75
|
|
76 Concrete server must expose a name
|
|
77
|
|
78 **********************************************************************/
|
|
79
|
|
80 protected abstract char[] toString();
|
|
81
|
|
82 /**********************************************************************
|
|
83
|
|
84 Concrete server must expose a ServerSocket factory
|
|
85
|
|
86 **********************************************************************/
|
|
87
|
|
88 protected abstract ServerSocket createSocket (InternetAddress bind, int backlog, bool reuse=false);
|
|
89
|
|
90 /**********************************************************************
|
|
91
|
|
92 Concrete server must expose a thread factory
|
|
93
|
|
94 **********************************************************************/
|
|
95
|
|
96 protected abstract void createThread (ServerSocket socket);
|
|
97
|
|
98 /**********************************************************************
|
|
99
|
|
100 Concrete server must expose a service handler
|
|
101
|
|
102 **********************************************************************/
|
|
103
|
|
104 abstract void service (IConduit conduit);
|
|
105
|
|
106 /**********************************************************************
|
|
107
|
|
108 Provide support for figuring out the remote address
|
|
109
|
|
110 **********************************************************************/
|
|
111
|
|
112 IPv4Address remoteAddress (IConduit conduit)
|
|
113 {
|
|
114 auto tmp = cast(SocketConduit) conduit;
|
|
115 if (tmp)
|
|
116 return cast(IPv4Address) tmp.socket.remoteAddress;
|
|
117 return null;
|
|
118 }
|
|
119
|
|
120 /**********************************************************************
|
|
121
|
|
122 Provide support for figuring out the remote address
|
|
123
|
|
124 **********************************************************************/
|
|
125
|
|
126 IPv4Address localAddress ()
|
|
127 {
|
|
128 return cast(IPv4Address) server.socket.localAddress;
|
|
129 }
|
|
130
|
|
131 /**********************************************************************
|
|
132
|
|
133 Provide support for figuring out the remote address
|
|
134
|
|
135 **********************************************************************/
|
|
136
|
|
137 char[] getRemoteAddress (IConduit conduit)
|
|
138 {
|
|
139 auto addr = remoteAddress (conduit);
|
|
140
|
|
141 if (addr)
|
|
142 return addr.toAddrString;
|
|
143 return "127.0.0.1";
|
|
144 }
|
|
145
|
|
146 /**********************************************************************
|
|
147
|
|
148 Provide support for figuring out the remote host. Not
|
|
149 currently implemented.
|
|
150
|
|
151 **********************************************************************/
|
|
152
|
|
153 char[] getRemoteHost (IConduit conduit)
|
|
154 {
|
|
155 return null;
|
|
156 }
|
|
157
|
|
158 /**********************************************************************
|
|
159
|
|
160 Return the local port we're attached to
|
|
161
|
|
162 **********************************************************************/
|
|
163
|
|
164 int getPort ()
|
|
165 {
|
|
166 return localAddress.port;
|
|
167 }
|
|
168
|
|
169 /**********************************************************************
|
|
170
|
|
171 Return the local address we're attached to
|
|
172
|
|
173 **********************************************************************/
|
|
174
|
|
175 char[] getHost ()
|
|
176 {
|
|
177 return localAddress.toAddrString;
|
|
178 }
|
|
179
|
|
180 /**********************************************************************
|
|
181
|
|
182 Return the logger associated with this server
|
|
183
|
|
184 **********************************************************************/
|
|
185
|
|
186 Logger getLogger ()
|
|
187 {
|
|
188 return logger;
|
|
189 }
|
|
190
|
|
191 /**********************************************************************
|
|
192
|
|
193 Start this server
|
|
194
|
|
195 **********************************************************************/
|
|
196
|
|
197 void start (bool reuse = false)
|
|
198 {
|
|
199 // have the subclass create a ServerSocket for us
|
|
200 server = createSocket (bind, backlog, reuse);
|
|
201
|
|
202 // instantiate and start all threads
|
|
203 for (auto i=threads; i-- > 0;)
|
|
204 createThread (server);
|
|
205
|
|
206 // indicate what's going on
|
|
207 logger.info (sprint ("Server {} started on {} with {} accept threads and {} backlogs",
|
|
208 this, localAddress, threads, backlog));
|
|
209 }
|
|
210 }
|