Issue #1516 - Delay starting of WebSocketClient
This commit is contained in:
parent
b0edf18ad9
commit
753ed9e603
|
@ -46,12 +46,14 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.util.thread.ShutdownThread;
|
||||
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||
import org.eclipse.jetty.websocket.client.io.UpgradeListener;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.scopes.DelegatedContainerScope;
|
||||
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||
import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner;
|
||||
|
@ -81,6 +83,7 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
|||
private final EncoderFactory encoderFactory;
|
||||
/** The jetty websocket client in use for this container */
|
||||
private final WebSocketClient client;
|
||||
private final boolean internalClient;
|
||||
/** Tracking for all declared Client endpoints */
|
||||
private final Map<Class<?>, EndpointMetadata> endpointClientMetadataCache;
|
||||
|
||||
|
@ -99,26 +102,74 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
|||
*
|
||||
* @param scope the scope of the ServerContainer
|
||||
*/
|
||||
public ClientContainer(WebSocketContainerScope scope)
|
||||
public ClientContainer(final WebSocketContainerScope scope)
|
||||
{
|
||||
boolean trustAll = Boolean.getBoolean("org.eclipse.jetty.websocket.jsr356.ssl-trust-all");
|
||||
|
||||
this.scopeDelegate = scope;
|
||||
client = new WebSocketClient(scope,
|
||||
new JsrEventDriverFactory(scope),
|
||||
String jsr356TrustAll = System.getProperty("org.eclipse.jetty.websocket.jsr356.ssl-trust-all");
|
||||
|
||||
WebSocketContainerScope clientScope;
|
||||
if (scope.getPolicy().getBehavior() == WebSocketBehavior.CLIENT)
|
||||
{
|
||||
clientScope = scope;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need to wrap the scope for the CLIENT Policy behaviors
|
||||
clientScope = new DelegatedContainerScope(WebSocketPolicy.newClientPolicy(), scope);
|
||||
}
|
||||
|
||||
this.scopeDelegate = clientScope;
|
||||
this.client = new WebSocketClient(scopeDelegate,
|
||||
new JsrEventDriverFactory(scopeDelegate),
|
||||
new JsrSessionFactory(this));
|
||||
client.getSslContextFactory().setTrustAll(trustAll);
|
||||
addBean(client);
|
||||
|
||||
this.internalClient = true;
|
||||
|
||||
if(jsr356TrustAll != null)
|
||||
{
|
||||
boolean trustAll = Boolean.parseBoolean(jsr356TrustAll);
|
||||
client.getSslContextFactory().setTrustAll(trustAll);
|
||||
}
|
||||
|
||||
this.endpointClientMetadataCache = new ConcurrentHashMap<>();
|
||||
this.decoderFactory = new DecoderFactory(this,PrimitiveDecoderMetadataSet.INSTANCE);
|
||||
this.encoderFactory = new EncoderFactory(this,PrimitiveEncoderMetadataSet.INSTANCE);
|
||||
|
||||
ShutdownThread.register(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a ClientContainer with a specific WebSocketClient in mind.
|
||||
*
|
||||
* @param client the WebSocketClient to use.
|
||||
*/
|
||||
public ClientContainer(WebSocketClient client)
|
||||
{
|
||||
this.scopeDelegate = client;
|
||||
this.client = client;
|
||||
this.internalClient = false;
|
||||
|
||||
this.endpointClientMetadataCache = new ConcurrentHashMap<>();
|
||||
this.decoderFactory = new DecoderFactory(this,PrimitiveDecoderMetadataSet.INSTANCE);
|
||||
this.encoderFactory = new EncoderFactory(this,PrimitiveEncoderMetadataSet.INSTANCE);
|
||||
}
|
||||
|
||||
private Session connect(EndpointInstance instance, URI path) throws IOException
|
||||
{
|
||||
synchronized (this.client)
|
||||
{
|
||||
if (this.internalClient && !this.client.isStarted())
|
||||
{
|
||||
try
|
||||
{
|
||||
this.client.start();
|
||||
addManaged(this.client);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException("Unable to start Client", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Objects.requireNonNull(instance,"EndpointInstance cannot be null");
|
||||
Objects.requireNonNull(path,"Path cannot be null");
|
||||
|
||||
|
|
|
@ -29,6 +29,34 @@ import javax.websocket.WebSocketContainer;
|
|||
*/
|
||||
public class JettyClientContainerProvider extends ContainerProvider
|
||||
{
|
||||
private static Object lock = new Object();
|
||||
private static ClientContainer INSTANCE;
|
||||
|
||||
public static ClientContainer getInstance()
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static void stop() throws Exception
|
||||
{
|
||||
synchronized (lock)
|
||||
{
|
||||
if (INSTANCE == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
INSTANCE.stop();
|
||||
}
|
||||
finally
|
||||
{
|
||||
INSTANCE = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by {@link ContainerProvider#getWebSocketContainer()} to get a new instance
|
||||
* of the Client {@link WebSocketContainer}.
|
||||
|
@ -36,16 +64,22 @@ public class JettyClientContainerProvider extends ContainerProvider
|
|||
@Override
|
||||
protected WebSocketContainer getContainer()
|
||||
{
|
||||
ClientContainer container = new ClientContainer();
|
||||
try
|
||||
synchronized (lock)
|
||||
{
|
||||
// We need to start this container properly.
|
||||
container.start();
|
||||
return container;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException("Unable to start Client Container",e);
|
||||
if (INSTANCE == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
INSTANCE = new ClientContainer();
|
||||
INSTANCE.start();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException("Unable to start Client Container", e);
|
||||
}
|
||||
}
|
||||
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.jsr356;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.hasItem;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.ThreadInfo;
|
||||
import java.lang.management.ThreadMXBean;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.websocket.ContainerProvider;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DelayedStartClientTest
|
||||
{
|
||||
@Before
|
||||
public void stopClientContainer() throws Exception
|
||||
{
|
||||
JettyClientContainerProvider.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoExtraHttpClientThreads()
|
||||
{
|
||||
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
||||
assertThat("Container", container, notNullValue());
|
||||
|
||||
List<String> threadNames = getThreadNames();
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("SimpleContainerScope.Executor@"))));
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("HttpClient@"))));
|
||||
}
|
||||
|
||||
private List<String> getThreadNames()
|
||||
{
|
||||
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
|
||||
ThreadInfo[] threads = threadMXBean.dumpAllThreads(false, false);
|
||||
List<String> ret = new ArrayList<>();
|
||||
for (ThreadInfo info : threads)
|
||||
{
|
||||
ret.add(info.getThreadName());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,347 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.jsr356.server;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.hasItem;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.CoreMatchers.startsWith;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.ThreadInfo;
|
||||
import java.lang.management.ThreadMXBean;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.websocket.ContainerProvider;
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.OnMessage;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
import javax.websocket.server.ServerEndpoint;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.websocket.api.util.WSURI;
|
||||
import org.eclipse.jetty.websocket.jsr356.ClientContainer;
|
||||
import org.eclipse.jetty.websocket.jsr356.JettyClientContainerProvider;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DelayedStartClientOnServerTest
|
||||
{
|
||||
@ServerEndpoint("/echo")
|
||||
public static class EchoSocket
|
||||
{
|
||||
@OnMessage
|
||||
public String echo(String msg)
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void stopClientContainer() throws Exception
|
||||
{
|
||||
JettyClientContainerProvider.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Using the Client specific techniques of JSR356, connect to the echo socket
|
||||
* and perform an echo request.
|
||||
*/
|
||||
public static class ClientConnectServlet extends HttpServlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||
{
|
||||
// Client specific technique
|
||||
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
||||
try
|
||||
{
|
||||
URI wsURI = WSURI.toWebsocket(req.getRequestURL()).resolve("/echo");
|
||||
Session session = container.connectToServer(new Endpoint()
|
||||
{
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
}, wsURI);
|
||||
// don't care about the data sent, just the connect itself.
|
||||
session.getBasicRemote().sendText("Hello");
|
||||
session.close();
|
||||
resp.setContentType("text/plain");
|
||||
resp.getWriter().println("Connected to " + wsURI);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new ServletException(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Using the Server specific techniques of JSR356, connect to the echo socket
|
||||
* and perform an echo request.
|
||||
*/
|
||||
public static class ServerConnectServlet extends HttpServlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||
{
|
||||
// Server specific technique
|
||||
javax.websocket.server.ServerContainer container =
|
||||
(javax.websocket.server.ServerContainer)
|
||||
req.getServletContext().getAttribute("javax.websocket.server.ServerContainer");
|
||||
try
|
||||
{
|
||||
URI wsURI = WSURI.toWebsocket(req.getRequestURL()).resolve("/echo");
|
||||
Session session = container.connectToServer(new Endpoint()
|
||||
{
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
}, wsURI);
|
||||
// don't care about the data sent, just the connect itself.
|
||||
session.getBasicRemote().sendText("Hello");
|
||||
session.close();
|
||||
resp.setContentType("text/plain");
|
||||
resp.getWriter().println("Connected to " + wsURI);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new ServletException(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Using the Client specific techniques of JSR356, configure the WebSocketContainer.
|
||||
*/
|
||||
public static class ClientConfigureServlet extends HttpServlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||
{
|
||||
// Client specific technique
|
||||
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
||||
|
||||
try
|
||||
{
|
||||
container.setAsyncSendTimeout(5000);
|
||||
container.setDefaultMaxTextMessageBufferSize(1000);
|
||||
resp.setContentType("text/plain");
|
||||
resp.getWriter().printf("Configured %s - %s%n", container.getClass().getName(), container);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new ServletException(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Using the Server specific techniques of JSR356, configure the WebSocketContainer.
|
||||
*/
|
||||
public static class ServerConfigureServlet extends HttpServlet
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||
{
|
||||
// Server specific technique
|
||||
javax.websocket.server.ServerContainer container =
|
||||
(javax.websocket.server.ServerContainer)
|
||||
req.getServletContext().getAttribute("javax.websocket.server.ServerContainer");
|
||||
try
|
||||
{
|
||||
container.setAsyncSendTimeout(5000);
|
||||
container.setDefaultMaxTextMessageBufferSize(1000);
|
||||
resp.setContentType("text/plain");
|
||||
resp.getWriter().printf("Configured %s - %s%n", container.getClass().getName(), container);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new ServletException(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoExtraHttpClientThreads() throws Exception
|
||||
{
|
||||
Server server = new Server(0);
|
||||
ServletContextHandler contextHandler = new ServletContextHandler();
|
||||
server.setHandler(contextHandler);
|
||||
WebSocketServerContainerInitializer.configureContext(contextHandler);
|
||||
try
|
||||
{
|
||||
server.start();
|
||||
List<String> threadNames = getThreadNames();
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("SimpleContainerScope.Executor@"))));
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("HttpClient@"))));
|
||||
}
|
||||
finally
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpClientThreads_AfterClientConnectTo() throws Exception
|
||||
{
|
||||
Server server = new Server(0);
|
||||
ServletContextHandler contextHandler = new ServletContextHandler();
|
||||
server.setHandler(contextHandler);
|
||||
// Using JSR356 Client Techniques to connectToServer()
|
||||
contextHandler.addServlet(ClientConnectServlet.class, "/connect");
|
||||
javax.websocket.server.ServerContainer container = WebSocketServerContainerInitializer.configureContext(contextHandler);
|
||||
container.addEndpoint(EchoSocket.class);
|
||||
try
|
||||
{
|
||||
server.start();
|
||||
String response = GET(server.getURI().resolve("/connect"));
|
||||
assertThat("Response", response, startsWith("Connected to ws://"));
|
||||
List<String> threadNames = getThreadNames();
|
||||
assertThat("Threads", threadNames, hasItem(containsString("SimpleContainerScope.Executor@")));
|
||||
assertThat("Threads", threadNames, hasItem(containsString("HttpClient@")));
|
||||
}
|
||||
finally
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpClientThreads_AfterServerConnectTo() throws Exception
|
||||
{
|
||||
Server server = new Server(0);
|
||||
ServletContextHandler contextHandler = new ServletContextHandler();
|
||||
server.setHandler(contextHandler);
|
||||
// Using JSR356 Server Techniques to connectToServer()
|
||||
contextHandler.addServlet(ServerConnectServlet.class, "/connect");
|
||||
javax.websocket.server.ServerContainer container = WebSocketServerContainerInitializer.configureContext(contextHandler);
|
||||
container.addEndpoint(EchoSocket.class);
|
||||
try
|
||||
{
|
||||
server.start();
|
||||
String response = GET(server.getURI().resolve("/connect"));
|
||||
assertThat("Response", response, startsWith("Connected to ws://"));
|
||||
List<String> threadNames = getThreadNames();
|
||||
assertThat("Threads", threadNames, hasItem(containsString("HttpClient@")));
|
||||
}
|
||||
finally
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpClientThreads_AfterClientConfigure() throws Exception
|
||||
{
|
||||
Server server = new Server(0);
|
||||
ServletContextHandler contextHandler = new ServletContextHandler();
|
||||
server.setHandler(contextHandler);
|
||||
// Using JSR356 Client Techniques to configure WebSocketContainer
|
||||
contextHandler.addServlet(ClientConfigureServlet.class, "/configure");
|
||||
javax.websocket.server.ServerContainer container = WebSocketServerContainerInitializer.configureContext(contextHandler);
|
||||
container.addEndpoint(EchoSocket.class);
|
||||
try
|
||||
{
|
||||
server.start();
|
||||
String response = GET(server.getURI().resolve("/configure"));
|
||||
assertThat("Response", response, startsWith("Configured " + ClientContainer.class.getName()));
|
||||
List<String> threadNames = getThreadNames();
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("SimpleContainerScope.Executor@"))));
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("HttpClient@"))));
|
||||
}
|
||||
finally
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpClientThreads_AfterServerConfigure() throws Exception
|
||||
{
|
||||
Server server = new Server(0);
|
||||
ServletContextHandler contextHandler = new ServletContextHandler();
|
||||
server.setHandler(contextHandler);
|
||||
// Using JSR356 Server Techniques to configure WebSocketContainer
|
||||
contextHandler.addServlet(ServerConfigureServlet.class, "/configure");
|
||||
javax.websocket.server.ServerContainer container = WebSocketServerContainerInitializer.configureContext(contextHandler);
|
||||
container.addEndpoint(EchoSocket.class);
|
||||
try
|
||||
{
|
||||
server.start();
|
||||
String response = GET(server.getURI().resolve("/configure"));
|
||||
assertThat("Response", response, startsWith("Configured " + ServerContainer.class.getName()));
|
||||
List<String> threadNames = getThreadNames();
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("SimpleContainerScope.Executor@"))));
|
||||
assertThat("Threads", threadNames, not(hasItem(containsString("HttpClient@"))));
|
||||
}
|
||||
finally
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private String GET(URI destURI) throws IOException
|
||||
{
|
||||
HttpURLConnection http = (HttpURLConnection) destURI.toURL().openConnection();
|
||||
assertThat("HTTP GET (" + destURI + ") Response Code", http.getResponseCode(), is(200));
|
||||
try (InputStream in = http.getInputStream();
|
||||
InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
|
||||
StringWriter writer = new StringWriter())
|
||||
{
|
||||
IO.copy(reader, writer);
|
||||
return writer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getThreadNames()
|
||||
{
|
||||
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
|
||||
ThreadInfo[] threads = threadMXBean.dumpAllThreads(false, false);
|
||||
List<String> ret = new ArrayList<>();
|
||||
for (ThreadInfo info : threads)
|
||||
{
|
||||
ret.add(info.getThreadName());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -42,6 +42,7 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
|||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.eclipse.jetty.util.thread.ShutdownThread;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
||||
|
@ -54,6 +55,7 @@ import org.eclipse.jetty.websocket.common.WebSocketSession;
|
|||
import org.eclipse.jetty.websocket.common.WebSocketSessionFactory;
|
||||
import org.eclipse.jetty.websocket.common.events.EventDriverFactory;
|
||||
import org.eclipse.jetty.websocket.common.extensions.WebSocketExtensionFactory;
|
||||
import org.eclipse.jetty.websocket.common.scopes.DelegatedContainerScope;
|
||||
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||
|
||||
|
@ -72,7 +74,6 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
|||
private final WebSocketExtensionFactory extensionRegistry;
|
||||
private final EventDriverFactory eventDriverFactory;
|
||||
private final SessionFactory sessionFactory;
|
||||
private Masker masker;
|
||||
|
||||
private final int id = ThreadLocalRandom.current().nextInt();
|
||||
|
||||
|
@ -110,7 +111,6 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
|||
this.containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy(),new MappedByteBufferPool(),objectFactory);
|
||||
this.httpClient = httpClient;
|
||||
this.extensionRegistry = new WebSocketExtensionFactory(containerScope);
|
||||
this.masker = new RandomMasker();
|
||||
this.eventDriverFactory = new EventDriverFactory(containerScope);
|
||||
this.sessionFactory = new WebSocketSessionFactory(containerScope);
|
||||
}
|
||||
|
@ -234,7 +234,6 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
|||
|
||||
this.extensionRegistry = new WebSocketExtensionFactory(containerScope);
|
||||
|
||||
this.masker = new RandomMasker();
|
||||
this.eventDriverFactory = new EventDriverFactory(containerScope);
|
||||
this.sessionFactory = new WebSocketSessionFactory(containerScope);
|
||||
}
|
||||
|
@ -250,9 +249,20 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
|||
* @param sessionFactory
|
||||
* the SessionFactory to use
|
||||
*/
|
||||
public WebSocketClient(WebSocketContainerScope scope, EventDriverFactory eventDriverFactory, SessionFactory sessionFactory)
|
||||
public WebSocketClient(final WebSocketContainerScope scope, EventDriverFactory eventDriverFactory, SessionFactory sessionFactory)
|
||||
{
|
||||
this.containerScope = scope;
|
||||
WebSocketContainerScope clientScope;
|
||||
if (scope.getPolicy().getBehavior() == WebSocketBehavior.CLIENT)
|
||||
{
|
||||
clientScope = scope;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need to wrap the scope
|
||||
clientScope = new DelegatedContainerScope(WebSocketPolicy.newClientPolicy(), scope);
|
||||
}
|
||||
|
||||
this.containerScope = clientScope;
|
||||
SslContextFactory sslContextFactory = scope.getSslContextFactory();
|
||||
if(sslContextFactory == null)
|
||||
{
|
||||
|
@ -264,7 +274,6 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
|||
|
||||
this.extensionRegistry = new WebSocketExtensionFactory(containerScope);
|
||||
|
||||
this.masker = new RandomMasker();
|
||||
this.eventDriverFactory = eventDriverFactory;
|
||||
this.sessionFactory = sessionFactory;
|
||||
}
|
||||
|
@ -435,10 +444,14 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
|||
{
|
||||
return extensionRegistry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated not used, no replacement
|
||||
*/
|
||||
@Deprecated
|
||||
public Masker getMasker()
|
||||
{
|
||||
return masker;
|
||||
return new RandomMasker();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -603,7 +616,11 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
|||
{
|
||||
this.httpClient.setCookieStore(cookieStore);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated not used, configure threading in HttpClient instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setDaemon(boolean daemon)
|
||||
{
|
||||
// do nothing
|
||||
|
@ -619,10 +636,14 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
|
|||
{
|
||||
this.httpClient.setExecutor(executor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated not used, no replacement
|
||||
*/
|
||||
@Deprecated
|
||||
public void setMasker(Masker masker)
|
||||
{
|
||||
this.masker = masker;
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
public void setMaxBinaryMessageBufferSize(int max)
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.common.scopes;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
|
||||
public class DelegatedContainerScope implements WebSocketContainerScope
|
||||
{
|
||||
private final WebSocketPolicy policy;
|
||||
private final WebSocketContainerScope delegate;
|
||||
|
||||
public DelegatedContainerScope(WebSocketPolicy policy, WebSocketContainerScope parentScope)
|
||||
{
|
||||
this.policy = policy;
|
||||
this.delegate = parentScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBufferPool getBufferPool()
|
||||
{
|
||||
return this.delegate.getBufferPool();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getExecutor()
|
||||
{
|
||||
return this.delegate.getExecutor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DecoratedObjectFactory getObjectFactory()
|
||||
{
|
||||
return this.delegate.getObjectFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketPolicy getPolicy()
|
||||
{
|
||||
return this.policy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SslContextFactory getSslContextFactory()
|
||||
{
|
||||
return this.delegate.getSslContextFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning()
|
||||
{
|
||||
return this.delegate.isRunning();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionOpened(WebSocketSession session)
|
||||
{
|
||||
this.delegate.onSessionOpened(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionClosed(WebSocketSession session)
|
||||
{
|
||||
this.delegate.onSessionClosed(session);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue