@@ -181,6 +181,30 @@ public WebSocketServer(InetSocketAddress address, int decodercount, List<Draft>
181181 this (address , decodercount , drafts , new HashSet <WebSocket >());
182182 }
183183
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+
184208 /**
185209 * Creates a WebSocketServer that will attempt to bind/listen on the given <var>address</var>, and
186210 * comply with <code>Draft</code> version <var>draft</var>.
@@ -575,15 +599,22 @@ private void doWrite(SelectionKey key) throws WrappedIOException {
575599 private boolean doSetupSelectorAndServerThread () {
576600 selectorthread .setName ("WebSocketSelector-" + selectorthread .getId ());
577601 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+ }
579606 server .configureBlocking (false );
580607 ServerSocket socket = server .socket ();
581608 int receiveBufferSize = getReceiveBufferSize ();
582609 if (receiveBufferSize > 0 ) {
583610 socket .setReceiveBufferSize (receiveBufferSize );
584611 }
585612 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+ }
587618 selector = Selector .open ();
588619 server .register (selector , server .validOps ());
589620 startConnectionLostTimer ();
0 commit comments