1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.server;
20
21 import java.io.IOException;
22 import java.net.InetSocketAddress;
23 import java.net.ServerSocket;
24 import java.net.Socket;
25 import java.net.SocketException;
26 import java.nio.channels.Channel;
27 import java.nio.channels.SelectionKey;
28 import java.nio.channels.Selector;
29 import java.nio.channels.ServerSocketChannel;
30 import java.nio.channels.SocketChannel;
31 import java.util.concurrent.Executor;
32 import java.util.concurrent.Future;
33
34 import org.eclipse.jetty.io.ByteBufferPool;
35 import org.eclipse.jetty.io.Connection;
36 import org.eclipse.jetty.io.EndPoint;
37 import org.eclipse.jetty.io.ManagedSelector;
38 import org.eclipse.jetty.io.SelectChannelEndPoint;
39 import org.eclipse.jetty.io.SelectorManager;
40 import org.eclipse.jetty.util.Callback;
41 import org.eclipse.jetty.util.annotation.ManagedAttribute;
42 import org.eclipse.jetty.util.annotation.ManagedObject;
43 import org.eclipse.jetty.util.annotation.Name;
44 import org.eclipse.jetty.util.ssl.SslContextFactory;
45 import org.eclipse.jetty.util.thread.Scheduler;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 @ManagedObject("HTTP connector using NIO ByteChannels and Selectors")
78 public class ServerConnector extends AbstractNetworkConnector
79 {
80 private final SelectorManager _manager;
81 private volatile ServerSocketChannel _acceptChannel;
82 private volatile boolean _inheritChannel = false;
83 private volatile int _localPort = -1;
84 private volatile int _acceptQueueSize = 0;
85 private volatile boolean _reuseAddress = true;
86 private volatile int _lingerTime = -1;
87
88
89
90
91
92
93
94 public ServerConnector(
95 @Name("server") Server server)
96 {
97 this(server,null,null,null,-1,-1,new HttpConnectionFactory());
98 }
99
100
101
102
103
104
105
106
107
108
109
110 public ServerConnector(
111 @Name("server") Server server,
112 @Name("acceptors") int acceptors,
113 @Name("selectors") int selectors)
114 {
115 this(server,null,null,null,acceptors,selectors,new HttpConnectionFactory());
116 }
117
118
119
120
121
122
123
124
125
126
127
128
129 public ServerConnector(
130 @Name("server") Server server,
131 @Name("acceptors") int acceptors,
132 @Name("selectors") int selectors,
133 @Name("factories") ConnectionFactory... factories)
134 {
135 this(server,null,null,null,acceptors,selectors,factories);
136 }
137
138
139
140
141
142
143
144 public ServerConnector(
145 @Name("server") Server server,
146 @Name("factories") ConnectionFactory... factories)
147 {
148 this(server,null,null,null,-1,-1,factories);
149 }
150
151
152
153
154
155
156
157
158 public ServerConnector(
159 @Name("server") Server server,
160 @Name("sslContextFactory") SslContextFactory sslContextFactory)
161 {
162 this(server,null,null,null,-1,-1,AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory()));
163 }
164
165
166
167
168
169
170
171
172
173
174
175
176
177 public ServerConnector(
178 @Name("server") Server server,
179 @Name("acceptors") int acceptors,
180 @Name("selectors") int selectors,
181 @Name("sslContextFactory") SslContextFactory sslContextFactory)
182 {
183 this(server,null,null,null,acceptors,selectors,AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory()));
184 }
185
186
187
188
189
190
191
192
193 public ServerConnector(
194 @Name("server") Server server,
195 @Name("sslContextFactory") SslContextFactory sslContextFactory,
196 @Name("factories") ConnectionFactory... factories)
197 {
198 this(server, null, null, null, -1, -1, AbstractConnectionFactory.getFactories(sslContextFactory, factories));
199 }
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219 public ServerConnector(
220 @Name("server") Server server,
221 @Name("executor") Executor executor,
222 @Name("scheduler") Scheduler scheduler,
223 @Name("bufferPool") ByteBufferPool bufferPool,
224 @Name("acceptors") int acceptors,
225 @Name("selectors") int selectors,
226 @Name("factories") ConnectionFactory... factories)
227 {
228 super(server,executor,scheduler,bufferPool,acceptors,factories);
229 _manager = newSelectorManager(getExecutor(), getScheduler(),
230 selectors>0?selectors:Math.max(1,Math.min(4,Runtime.getRuntime().availableProcessors()/2)));
231 addBean(_manager, true);
232 setSelectorPriorityDelta(-1);
233 setAcceptorPriorityDelta(-2);
234 }
235
236 protected SelectorManager newSelectorManager(Executor executor, Scheduler scheduler, int selectors)
237 {
238 return new ServerConnectorManager(executor, scheduler, selectors);
239 }
240
241 @Override
242 protected void doStart() throws Exception
243 {
244 super.doStart();
245
246 if (getAcceptors()==0)
247 {
248 _acceptChannel.configureBlocking(false);
249 _manager.acceptor(_acceptChannel);
250 }
251 }
252
253 @Override
254 public boolean isOpen()
255 {
256 ServerSocketChannel channel = _acceptChannel;
257 return channel!=null && channel.isOpen();
258 }
259
260
261
262
263
264 @Deprecated
265 public int getSelectorPriorityDelta()
266 {
267 return _manager.getSelectorPriorityDelta();
268 }
269
270
271
272
273
274 @Deprecated
275 public void setSelectorPriorityDelta(int selectorPriorityDelta)
276 {
277 _manager.setSelectorPriorityDelta(selectorPriorityDelta);
278 }
279
280
281
282
283
284 public boolean isInheritChannel()
285 {
286 return _inheritChannel;
287 }
288
289
290
291
292
293
294
295
296
297
298
299
300 public void setInheritChannel(boolean inheritChannel)
301 {
302 _inheritChannel = inheritChannel;
303 }
304
305 @Override
306 public void open() throws IOException
307 {
308 if (_acceptChannel == null)
309 {
310 ServerSocketChannel serverChannel = null;
311 if (isInheritChannel())
312 {
313 Channel channel = System.inheritedChannel();
314 if (channel instanceof ServerSocketChannel)
315 serverChannel = (ServerSocketChannel)channel;
316 else
317 LOG.warn("Unable to use System.inheritedChannel() [{}]. Trying a new ServerSocketChannel at {}:{}", channel, getHost(), getPort());
318 }
319
320 if (serverChannel == null)
321 {
322 serverChannel = ServerSocketChannel.open();
323
324 InetSocketAddress bindAddress = getHost() == null ? new InetSocketAddress(getPort()) : new InetSocketAddress(getHost(), getPort());
325 serverChannel.socket().setReuseAddress(getReuseAddress());
326 serverChannel.socket().bind(bindAddress, getAcceptQueueSize());
327
328 _localPort = serverChannel.socket().getLocalPort();
329 if (_localPort <= 0)
330 throw new IOException("Server channel not bound");
331
332 addBean(serverChannel);
333 }
334
335 serverChannel.configureBlocking(true);
336 addBean(serverChannel);
337
338 _acceptChannel = serverChannel;
339 }
340 }
341
342 @Override
343 public Future<Void> shutdown()
344 {
345
346 return super.shutdown();
347 }
348
349 @Override
350 public void close()
351 {
352 ServerSocketChannel serverChannel = _acceptChannel;
353 _acceptChannel = null;
354
355 if (serverChannel != null)
356 {
357 removeBean(serverChannel);
358
359
360 if (serverChannel.isOpen())
361 {
362 try
363 {
364 serverChannel.close();
365 }
366 catch (IOException e)
367 {
368 LOG.warn(e);
369 }
370 }
371 }
372
373 _localPort = -2;
374 }
375
376 @Override
377 public void accept(int acceptorID) throws IOException
378 {
379 ServerSocketChannel serverChannel = _acceptChannel;
380 if (serverChannel != null && serverChannel.isOpen())
381 {
382 SocketChannel channel = serverChannel.accept();
383 accepted(channel);
384 }
385 }
386
387 private void accepted(SocketChannel channel) throws IOException
388 {
389 channel.configureBlocking(false);
390 Socket socket = channel.socket();
391 configure(socket);
392 _manager.accept(channel);
393 }
394
395 protected void configure(Socket socket)
396 {
397 try
398 {
399 socket.setTcpNoDelay(true);
400 if (_lingerTime >= 0)
401 socket.setSoLinger(true, _lingerTime / 1000);
402 else
403 socket.setSoLinger(false, 0);
404 }
405 catch (SocketException e)
406 {
407 LOG.ignore(e);
408 }
409 }
410
411 public SelectorManager getSelectorManager()
412 {
413 return _manager;
414 }
415
416 @Override
417 public Object getTransport()
418 {
419 return _acceptChannel;
420 }
421
422 @Override
423 @ManagedAttribute("local port")
424 public int getLocalPort()
425 {
426 return _localPort;
427 }
428
429 protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException
430 {
431 return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout());
432 }
433
434
435
436
437
438 @ManagedAttribute("TCP/IP solinger time or -1 to disable")
439 public int getSoLingerTime()
440 {
441 return _lingerTime;
442 }
443
444
445
446
447
448 public void setSoLingerTime(int lingerTime)
449 {
450 _lingerTime = lingerTime;
451 }
452
453
454
455
456 @ManagedAttribute("Accept Queue size")
457 public int getAcceptQueueSize()
458 {
459 return _acceptQueueSize;
460 }
461
462
463
464
465 public void setAcceptQueueSize(int acceptQueueSize)
466 {
467 _acceptQueueSize = acceptQueueSize;
468 }
469
470
471
472
473
474 public boolean getReuseAddress()
475 {
476 return _reuseAddress;
477 }
478
479
480
481
482
483 public void setReuseAddress(boolean reuseAddress)
484 {
485 _reuseAddress = reuseAddress;
486 }
487
488 protected class ServerConnectorManager extends SelectorManager
489 {
490 public ServerConnectorManager(Executor executor, Scheduler scheduler, int selectors)
491 {
492 super(executor, scheduler, selectors);
493 }
494
495 @Override
496 protected void accepted(SocketChannel channel) throws IOException
497 {
498 ServerConnector.this.accepted(channel);
499 }
500
501 @Override
502 protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey selectionKey) throws IOException
503 {
504 return ServerConnector.this.newEndPoint(channel, selectSet, selectionKey);
505 }
506
507 @Override
508 public Connection newConnection(SocketChannel channel, EndPoint endpoint, Object attachment) throws IOException
509 {
510 return getDefaultConnectionFactory().newConnection(ServerConnector.this, endpoint);
511 }
512
513 @Override
514 protected void endPointOpened(EndPoint endpoint)
515 {
516 super.endPointOpened(endpoint);
517 onEndPointOpened(endpoint);
518 }
519
520 @Override
521 protected void endPointClosed(EndPoint endpoint)
522 {
523 onEndPointClosed(endpoint);
524 super.endPointClosed(endpoint);
525 }
526 }
527 }