Issue #3167 - lazily create the WebSocketCoreClient
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
1999b23d67
commit
3bcb4d8229
|
@ -18,6 +18,21 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.javax.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Supplier;
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.ClientEndpointConfig;
|
||||
import javax.websocket.DeploymentException;
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.Extension;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
||||
|
@ -30,20 +45,6 @@ import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketContainer;
|
|||
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketExtensionConfig;
|
||||
import org.eclipse.jetty.websocket.javax.common.JavaxWebSocketFrameHandlerFactory;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.ClientEndpointConfig;
|
||||
import javax.websocket.DeploymentException;
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.Extension;
|
||||
import javax.websocket.Session;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* Container for Client use of the javax.websocket API.
|
||||
* <p>
|
||||
|
@ -52,25 +53,21 @@ import java.util.concurrent.Future;
|
|||
@ManagedObject("JSR356 Client Container")
|
||||
public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer implements javax.websocket.WebSocketContainer
|
||||
{
|
||||
protected final WebSocketCoreClient coreClient;
|
||||
protected WebSocketCoreClient coreClient;
|
||||
protected Supplier<WebSocketCoreClient> coreClientFactory;
|
||||
private final JavaxWebSocketClientFrameHandlerFactory frameHandlerFactory;
|
||||
private ClassLoader contextClassLoader;
|
||||
private DecoratedObjectFactory objectFactory;
|
||||
private WebSocketExtensionRegistry extensionRegistry;
|
||||
|
||||
public JavaxWebSocketClientContainer()
|
||||
{
|
||||
this(new WebSocketCoreClient());
|
||||
this.coreClient.getHttpClient().setName("Javax-WebSocketClient@" + Integer.toHexString(this.coreClient.getHttpClient().hashCode()));
|
||||
// We created WebSocketCoreClient, let lifecycle be managed by us
|
||||
addManaged(coreClient);
|
||||
this(() -> new WebSocketCoreClient());
|
||||
}
|
||||
|
||||
public JavaxWebSocketClientContainer(HttpClient httpClient)
|
||||
public JavaxWebSocketClientContainer(Supplier<WebSocketCoreClient> coreClientFactory)
|
||||
{
|
||||
this(new WebSocketCoreClient(httpClient));
|
||||
// We created WebSocketCoreClient, let lifecycle be managed by us
|
||||
addManaged(coreClient);
|
||||
this((WebSocketCoreClient)null);
|
||||
this.coreClientFactory = coreClientFactory;
|
||||
}
|
||||
|
||||
public JavaxWebSocketClientContainer(WebSocketCoreClient coreClient)
|
||||
|
@ -78,7 +75,6 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple
|
|||
super();
|
||||
this.coreClient = coreClient;
|
||||
this.addBean(this.coreClient);
|
||||
this.contextClassLoader = this.getClass().getClassLoader();
|
||||
this.objectFactory = new DecoratedObjectFactory();
|
||||
this.extensionRegistry = new WebSocketExtensionRegistry();
|
||||
this.frameHandlerFactory = new JavaxWebSocketClientFrameHandlerFactory(this);
|
||||
|
@ -98,11 +94,18 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple
|
|||
|
||||
protected HttpClient getHttpClient()
|
||||
{
|
||||
return coreClient.getHttpClient();
|
||||
return getWebSocketCoreClient().getHttpClient();
|
||||
}
|
||||
|
||||
protected WebSocketCoreClient getWebSocketCoreClient() throws Exception
|
||||
protected WebSocketCoreClient getWebSocketCoreClient()
|
||||
{
|
||||
if (coreClient == null)
|
||||
{
|
||||
coreClient = coreClientFactory.get();
|
||||
this.coreClient.getHttpClient().setName("Javax-WebSocketClient@" + Integer.toHexString(this.coreClient.getHttpClient().hashCode()));
|
||||
addManaged(coreClient);
|
||||
}
|
||||
|
||||
return coreClient;
|
||||
}
|
||||
|
||||
|
@ -132,7 +135,7 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple
|
|||
Objects.requireNonNull(configuredEndpoint, "WebSocket configured endpoint cannot be null");
|
||||
Objects.requireNonNull(destURI, "Destination URI cannot be null");
|
||||
|
||||
ClientUpgradeRequestImpl upgradeRequest = new ClientUpgradeRequestImpl(this, coreClient, destURI, configuredEndpoint);
|
||||
ClientUpgradeRequestImpl upgradeRequest = new ClientUpgradeRequestImpl(this, getWebSocketCoreClient(), destURI, configuredEndpoint);
|
||||
|
||||
EndpointConfig config = configuredEndpoint.getConfig();
|
||||
if (config != null && config instanceof ClientEndpointConfig)
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.time.Duration;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.websocket.DeploymentException;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
@ -40,10 +39,10 @@ import org.eclipse.jetty.util.log.Log;
|
|||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry;
|
||||
import org.eclipse.jetty.websocket.core.client.WebSocketCoreClient;
|
||||
import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainer;
|
||||
import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException;
|
||||
import org.eclipse.jetty.websocket.javax.server.internal.AnnotatedServerEndpointConfig;
|
||||
import org.eclipse.jetty.websocket.javax.server.internal.JavaxWebSocketCreator;
|
||||
import org.eclipse.jetty.websocket.javax.common.InvalidWebSocketException;
|
||||
import org.eclipse.jetty.websocket.javax.client.JavaxWebSocketClientContainer;
|
||||
import org.eclipse.jetty.websocket.javax.server.internal.UndefinedServerEndpointConfig;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreatorMapping;
|
||||
|
||||
|
@ -83,13 +82,20 @@ public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer
|
|||
|
||||
/**
|
||||
* Main entry point for {@link JavaxWebSocketServerContainerInitializer}.
|
||||
*
|
||||
* @param webSocketCreatorMapping the {@link WebSocketCreatorMapping} that this container belongs to
|
||||
* @param httpClient the {@link HttpClient} instance to use
|
||||
*/
|
||||
public JavaxWebSocketServerContainer(WebSocketCreatorMapping webSocketCreatorMapping, HttpClient httpClient, Executor executor)
|
||||
{
|
||||
super(new WebSocketCoreClient(httpClient));
|
||||
super(() ->
|
||||
{
|
||||
// TODO Can the client share the websocket or container buffer pool
|
||||
WebSocketCoreClient client = new WebSocketCoreClient(httpClient);
|
||||
if (executor != null && httpClient == null)
|
||||
client.getHttpClient().setExecutor(executor);
|
||||
|
||||
return client;
|
||||
});
|
||||
this._webSocketCreatorMapping = webSocketCreatorMapping;
|
||||
this.executor = executor;
|
||||
this.frameHandlerFactory = new JavaxWebSocketServerFrameHandlerFactory(this);
|
||||
|
@ -125,24 +131,6 @@ public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer
|
|||
return this._webSocketCreatorMapping.getObjectFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WebSocketCoreClient getWebSocketCoreClient() throws Exception
|
||||
{
|
||||
// Lazy Start Http Client
|
||||
if (!coreClient.getHttpClient().isStarted())
|
||||
{
|
||||
coreClient.getHttpClient().start();
|
||||
}
|
||||
|
||||
// Lazy Start WebSocket Client
|
||||
if (!coreClient.isStarted())
|
||||
{
|
||||
coreClient.start();
|
||||
}
|
||||
|
||||
return coreClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EndpointConfig newEmptyConfig(Object endpoint)
|
||||
{
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.websocket.javax.server;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.servlet.ServletContainerInitializer;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
|
@ -153,20 +152,8 @@ public class JavaxWebSocketServerContainerInitializer implements ServletContaine
|
|||
if (executor == null)
|
||||
executor = context.getServer().getThreadPool();
|
||||
|
||||
// Do we need to make a client?
|
||||
if (httpClient == null)
|
||||
{
|
||||
// TODO Do we always need a HttpClient?
|
||||
// TODO Can the client share the websocket or container buffer pool
|
||||
httpClient = new HttpClient();
|
||||
httpClient.setName("Javax-WebSocketServer@" + Integer.toHexString(httpClient.hashCode()));
|
||||
if (httpClient!=null && httpClient.getExecutor()==null)
|
||||
httpClient.setExecutor(executor);
|
||||
context.addBean(httpClient, true);
|
||||
}
|
||||
else if (httpClient.getExecutor() == null)
|
||||
{
|
||||
httpClient.setExecutor(executor);
|
||||
}
|
||||
|
||||
// Create the Jetty ServerContainer implementation
|
||||
JavaxWebSocketServerContainer jettyContainer = new JavaxWebSocketServerContainer(webSocketCreatorMapping, httpClient, executor);
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
|
||||
package org.eclipse.jetty.websocket.core.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
|
@ -29,10 +33,6 @@ import org.eclipse.jetty.websocket.core.ExtensionConfig;
|
|||
import org.eclipse.jetty.websocket.core.FrameHandler;
|
||||
import org.eclipse.jetty.websocket.core.WebSocketExtensionRegistry;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class WebSocketCoreClient extends ContainerLifeCycle implements FrameHandler.CoreCustomizer
|
||||
{
|
||||
|
||||
|
@ -51,12 +51,7 @@ public class WebSocketCoreClient extends ContainerLifeCycle implements FrameHand
|
|||
|
||||
public WebSocketCoreClient()
|
||||
{
|
||||
this(new HttpClient(new SslContextFactory()));
|
||||
// TODO is there more HttpClient configuration we should do by default?
|
||||
httpClient.getSslContextFactory().setEndpointIdentificationAlgorithm("HTTPS");
|
||||
httpClient.setName("WSCoreClient");
|
||||
// Internally created, let websocket client's lifecycle manage it.
|
||||
addManaged(httpClient);
|
||||
this(null,null);
|
||||
}
|
||||
|
||||
public WebSocketCoreClient(HttpClient httpClient)
|
||||
|
@ -66,7 +61,13 @@ public class WebSocketCoreClient extends ContainerLifeCycle implements FrameHand
|
|||
|
||||
public WebSocketCoreClient(HttpClient httpClient, FrameHandler.CoreCustomizer customizer)
|
||||
{
|
||||
this.httpClient = httpClient == null?new HttpClient():httpClient;
|
||||
if (httpClient==null)
|
||||
{
|
||||
httpClient = new HttpClient(new SslContextFactory());
|
||||
httpClient.getSslContextFactory().setEndpointIdentificationAlgorithm("HTTPS");
|
||||
httpClient.setName(String.format("%s@%x",getClass().getSimpleName(),hashCode()));
|
||||
}
|
||||
this.httpClient = httpClient;
|
||||
this.extensionRegistry = new WebSocketExtensionRegistry();
|
||||
this.objectFactory = new DecoratedObjectFactory();
|
||||
this.customizer = customizer;
|
||||
|
|
Loading…
Reference in New Issue