Skip to content

Commit 64796cd

Browse files
committed
Add support for creating server from existing Channel
See #1440 The main motivation for this feature is the ability to integrate with on-demand socket activation.
1 parent 3b29042 commit 64796cd

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

src/main/java/org/java_websocket/server/WebSocketServer.java

+32-2
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,29 @@ 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+
* @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+
184207
/**
185208
* Creates a WebSocketServer that will attempt to bind/listen on the given <var>address</var>, and
186209
* comply with <code>Draft</code> version <var>draft</var>.
@@ -575,15 +598,22 @@ private void doWrite(SelectionKey key) throws WrappedIOException {
575598
private boolean doSetupSelectorAndServerThread() {
576599
selectorthread.setName("WebSocketSelector-" + selectorthread.getId());
577600
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+
}
579605
server.configureBlocking(false);
580606
ServerSocket socket = server.socket();
581607
int receiveBufferSize = getReceiveBufferSize();
582608
if (receiveBufferSize > 0) {
583609
socket.setReceiveBufferSize(receiveBufferSize);
584610
}
585611
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+
}
587617
selector = Selector.open();
588618
server.register(selector, server.validOps());
589619
startConnectionLostTimer();

0 commit comments

Comments
 (0)