@@ -181,6 +181,30 @@ 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
+ /**
200
+ * @param existingChannel An already open and bound server socket channel, which this server will use.
201
+ * For example, it can be System.inheritedChannel() to implement socket activation.
202
+ */
203
+ public WebSocketServer (ServerSocketChannel existingChannel ) {
204
+ this (checkAddressOfExistingChannel (existingChannel ));
205
+ this .server = existingChannel ;
206
+ }
207
+
184
208
/**
185
209
* Creates a WebSocketServer that will attempt to bind/listen on the given <var>address</var>, and
186
210
* comply with <code>Draft</code> version <var>draft</var>.
@@ -575,15 +599,22 @@ private void doWrite(SelectionKey key) throws WrappedIOException {
575
599
private boolean doSetupSelectorAndServerThread () {
576
600
selectorthread .setName ("WebSocketSelector-" + selectorthread .getId ());
577
601
try {
578
- server = ServerSocketChannel .open ();
602
+ if (server == null ) {
603
+ server = ServerSocketChannel .open ();
604
+ // If 'server' is not null, that means WebSocketServer was created from existing channel.
605
+ }
579
606
server .configureBlocking (false );
580
607
ServerSocket socket = server .socket ();
581
608
int receiveBufferSize = getReceiveBufferSize ();
582
609
if (receiveBufferSize > 0 ) {
583
610
socket .setReceiveBufferSize (receiveBufferSize );
584
611
}
585
612
socket .setReuseAddress (isReuseAddr ());
586
- socket .bind (address , getMaxPendingConnections ());
613
+ // Socket may be already bound, if an existing channel was passed to constructor.
614
+ // In this case we cannot modify backlog size from pure Java code, so leave it as is.
615
+ if (!socket .isBound ()) {
616
+ socket .bind (address , getMaxPendingConnections ());
617
+ }
587
618
selector = Selector .open ();
588
619
server .register (selector , server .validOps ());
589
620
startConnectionLostTimer ();
0 commit comments