@@ -181,6 +181,29 @@ public WebSocketServer(InetSocketAddress address, int decodercount, List<Draft>
181
181
this (address , decodercount , drafts , new HashSet <WebSocket >());
182
182
}
183
183
184
+ // Small internal helper function to get around limitations of Java constructors.
185
+ private static InetSocketAddress checkAddressOfExistingChannel (ServerSocketChannel existingChannel ) {
186
+ assert existingChannel .isOpen ();
187
+ SocketAddress addr ;
188
+ try {
189
+ addr = existingChannel .getLocalAddress ();
190
+ } catch (IOException e ) {
191
+ throw new IllegalArgumentException ("Could not get address of channel passed to WebSocketServer, make sure it is bound" , e );
192
+ }
193
+ if (addr == null ) {
194
+ throw new IllegalArgumentException ("Could not get address of channel passed to WebSocketServer, make sure it is bound" );
195
+ }
196
+ return (InetSocketAddress )addr ;
197
+ }
198
+ /**
199
+ * @param existingChannel An already open and bound server socket channel, which this server will use.
200
+ * For example, it can be System.inheritedChannel() to implement socket activation.
201
+ */
202
+ public WebSocketServer (ServerSocketChannel existingChannel ) {
203
+ this (checkAddressOfExistingChannel (existingChannel ));
204
+ this .server = existingChannel ;
205
+ }
206
+
184
207
/**
185
208
* Creates a WebSocketServer that will attempt to bind/listen on the given <var>address</var>, and
186
209
* comply with <code>Draft</code> version <var>draft</var>.
@@ -575,15 +598,22 @@ private void doWrite(SelectionKey key) throws WrappedIOException {
575
598
private boolean doSetupSelectorAndServerThread () {
576
599
selectorthread .setName ("WebSocketSelector-" + selectorthread .getId ());
577
600
try {
578
- server = ServerSocketChannel .open ();
601
+ if (server == null ) {
602
+ server = ServerSocketChannel .open ();
603
+ // If 'server' is not null, that means WebSocketServer was created from existing channel.
604
+ }
579
605
server .configureBlocking (false );
580
606
ServerSocket socket = server .socket ();
581
607
int receiveBufferSize = getReceiveBufferSize ();
582
608
if (receiveBufferSize > 0 ) {
583
609
socket .setReceiveBufferSize (receiveBufferSize );
584
610
}
585
611
socket .setReuseAddress (isReuseAddr ());
586
- socket .bind (address , getMaxPendingConnections ());
612
+ // Socket may be already bound, if an existing channel was passed to constructor.
613
+ // In this case we cannot modify backlog size from pure Java code, so leave it as is.
614
+ if (!socket .isBound ()) {
615
+ socket .bind (address , getMaxPendingConnections ());
616
+ }
587
617
selector = Selector .open ();
588
618
server .register (selector , server .validOps ());
589
619
startConnectionLostTimer ();
0 commit comments