Skip to content

Instantly share code, notes, and snippets.

@davidvollmar
Created March 30, 2015 18:38
Show Gist options
  • Save davidvollmar/d3ff37be35f218dbdadc to your computer and use it in GitHub Desktop.
Save davidvollmar/d3ff37be35f218dbdadc to your computer and use it in GitHub Desktop.
Enabling websocket for spark-java
import com.google.gson.Gson;
import model.GameState;
import model.GameStateProvider;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import java.io.IOException;
/**
* Example EchoSocket using Adapter.
*/
public class AdapterEchoSocket extends WebSocketAdapter {
@Override
public void onWebSocketText(String message) {
getRemote().sendString(message); // add your websocket logic here
}
}
public static void main(String[] args) {
setup();
Spark.get("/", (res, req) -> "Index");
setupWS();
}
private static void setup() {
Spark.port(8080);
}
private static void setupWS(){
ServletContextHandler servletContextHandler = new ServletContextHandler(null, "/",true,false);
servletContextHandler.addServlet(MyEchoServlet.class, "/websocket");
List<Handler> foo = new ArrayList<>();
foo.add(servletContextHandler);
boolean ok = false;
//this is because we need to wait before spark is loaded entirely.
while(!ok){
try{
// adding external handlers is normally not exposed
Spark.setExternalHandlers(foo);
ok = true;
System.out.println("Websocket registered!");
}catch (NullPointerException npe){}
}
}
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import javax.servlet.annotation.WebServlet;
// register your adapter class
@WebServlet(name = "MyEcho WebSocket Servlet")
@WebSocket
public class MyEchoServlet extends WebSocketServlet {
@Override
public void configure(WebSocketServletFactory factory) {
System.out.println("ws configuted");
factory.getPolicy().setIdleTimeout(10000);
factory.register(AdapterEchoSocket.class);
}
}
package spark;
import org.eclipse.jetty.server.Handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import spark.route.RouteMatcherFactory;
import spark.route.SimpleRouteMatcher;
import spark.servlet.SparkFilter;
import spark.webserver.SparkServer;
import spark.webserver.SparkServerFactory;
import java.util.List;
/**
* Spark base class - customized to allow external handlers.
*/
public abstract class SparkBase {
private static final Logger LOG = LoggerFactory.getLogger("spark.Spark");
public static final int SPARK_DEFAULT_PORT = 4567;
protected static final String DEFAULT_ACCEPT_TYPE = "*/*";
protected static boolean initialized = false;
protected static int port = SPARK_DEFAULT_PORT;
protected static String ipAddress = "0.0.0.0";
protected static String keystoreFile;
protected static String keystorePassword;
protected static String truststoreFile;
protected static String truststorePassword;
protected static String staticFileFolder = null;
protected static String externalStaticFileFolder = null;
protected static SparkServer server;
protected static SimpleRouteMatcher routeMatcher;
private static boolean runFromServlet;
private static boolean servletStaticLocationSet;
private static boolean servletExternalStaticLocationSet;
/**
* Set the IP address that Spark should listen on. If not called the default
* address is '0.0.0.0'. This has to be called before any route mapping is
* done.
*
* @param ipAddress The ipAddress
* @deprecated replaced by {@link #ipAddress(String)}
*/
public static synchronized void setIpAddress(String ipAddress) {
if (initialized) {
throwBeforeRouteMappingException();
}
Spark.ipAddress = ipAddress;
}
// expose setExternalHandlers, not available normally.
public static void setExternalHandlers(List<Handler> handlers){
server.setExternalHandlers(handlers);
}
/**
* Set the IP address that Spark should listen on. If not called the default
* address is '0.0.0.0'. This has to be called before any route mapping is
* done.
*
* @param ipAddress The ipAddress
*/
public static synchronized void ipAddress(String ipAddress) {
if (initialized) {
throwBeforeRouteMappingException();
}
Spark.ipAddress = ipAddress;
}
/**
* Set the port that Spark should listen on. If not called the default port
* is 4567. This has to be called before any route mapping is done.
* If provided port = 0 then the an arbitrary available port will be used.
*
* @param port The port number
* @deprecated replaced by {@link #port(int)}
*/
public static synchronized void setPort(int port) {
if (initialized) {
throwBeforeRouteMappingException();
}
Spark.port = port;
}
/**
* Set the port that Spark should listen on. If not called the default port
* is 4567. This has to be called before any route mapping is done.
* If provided port = 0 then the an arbitrary available port will be used.
*
* @param port The port number
*/
public static synchronized void port(int port) {
if (initialized) {
throwBeforeRouteMappingException();
}
Spark.port = port;
}
/**
* Set the connection to be secure, using the specified keystore and
* truststore. This has to be called before any route mapping is done. You
* have to supply a keystore file, truststore file is optional (keystore
* will be reused).
* This method is only relevant when using embedded Jetty servers. It should
* not be used if you are using Servlets, where you will need to secure the
* connection in the servlet container
*
* @param keystoreFile The keystore file location as string
* @param keystorePassword the password for the keystore
* @param truststoreFile the truststore file location as string, leave null to reuse
* keystore
* @param truststorePassword the trust store password
* @deprecated replaced by {@link #secure(String, String, String, String)}
*/
public static synchronized void setSecure(String keystoreFile,
String keystorePassword,
String truststoreFile,
String truststorePassword) {
if (initialized) {
throwBeforeRouteMappingException();
}
if (keystoreFile == null) {
throw new IllegalArgumentException(
"Must provide a keystore file to run secured");
}
Spark.keystoreFile = keystoreFile;
Spark.keystorePassword = keystorePassword;
Spark.truststoreFile = truststoreFile;
Spark.truststorePassword = truststorePassword;
}
/**
* Set the connection to be secure, using the specified keystore and
* truststore. This has to be called before any route mapping is done. You
* have to supply a keystore file, truststore file is optional (keystore
* will be reused).
* This method is only relevant when using embedded Jetty servers. It should
* not be used if you are using Servlets, where you will need to secure the
* connection in the servlet container
*
* @param keystoreFile The keystore file location as string
* @param keystorePassword the password for the keystore
* @param truststoreFile the truststore file location as string, leave null to reuse
* keystore
* @param truststorePassword the trust store password
*/
public static synchronized void secure(String keystoreFile,
String keystorePassword,
String truststoreFile,
String truststorePassword) {
if (initialized) {
throwBeforeRouteMappingException();
}
if (keystoreFile == null) {
throw new IllegalArgumentException(
"Must provide a keystore file to run secured");
}
Spark.keystoreFile = keystoreFile;
Spark.keystorePassword = keystorePassword;
Spark.truststoreFile = truststoreFile;
Spark.truststorePassword = truststorePassword;
}
/**
* Sets the folder in classpath serving static files. Observe: this method
* must be called before all other methods.
*
* @param folder the folder in classpath.
*/
public static synchronized void staticFileLocation(String folder) {
if (initialized && !runFromServlet) {
throwBeforeRouteMappingException();
}
staticFileFolder = folder;
if (!servletStaticLocationSet) {
if (runFromServlet) {
SparkFilter.configureStaticResources(staticFileFolder);
servletStaticLocationSet = true;
}
} else {
LOG.warn("Static file location has already been set");
}
}
/**
* Sets the external folder serving static files. <b>Observe: this method
* must be called before all other methods.</b>
*
* @param externalFolder the external folder serving static files.
*/
public static synchronized void externalStaticFileLocation(String externalFolder) {
if (initialized && !runFromServlet) {
throwBeforeRouteMappingException();
}
externalStaticFileFolder = externalFolder;
if (!servletExternalStaticLocationSet) {
if (runFromServlet) {
SparkFilter.configureExternalStaticResources(externalStaticFileFolder);
servletExternalStaticLocationSet = true;
}
} else {
LOG.warn("External static file location has already been set");
}
}
private static void throwBeforeRouteMappingException() {
throw new IllegalStateException(
"This must be done before route mapping has begun");
}
private static boolean hasMultipleHandlers() {
return staticFileFolder != null || externalStaticFileFolder != null;
}
/**
* Stops the Spark server and clears all routes
*/
public static synchronized void stop() {
if (server != null) {
routeMatcher.clearRoutes();
server.stop();
}
initialized = false;
}
static synchronized void runFromServlet() {
runFromServlet = true;
if (!initialized) {
routeMatcher = RouteMatcherFactory.get();
initialized = true;
}
}
/**
* Wraps the route in RouteImpl
*
* @param path the path
* @param route the route
* @return the wrapped route
*/
protected static RouteImpl wrap(final String path, final Route route) {
return wrap(path, DEFAULT_ACCEPT_TYPE, route);
}
/**
* Wraps the route in RouteImpl
*
* @param path the path
* @param acceptType the accept type
* @param route the route
* @return the wrapped route
*/
protected static RouteImpl wrap(final String path, String acceptType, final Route route) {
if (acceptType == null) {
acceptType = DEFAULT_ACCEPT_TYPE;
}
RouteImpl impl = new RouteImpl(path, acceptType) {
@Override
public Object handle(Request request, Response response) throws Exception {
return route.handle(request, response);
}
};
return impl;
}
/**
* Wraps the filter in FilterImpl
*
* @param path the path
* @param filter the filter
* @return the wrapped route
*/
protected static FilterImpl wrap(final String path, final Filter filter) {
return wrap(path, DEFAULT_ACCEPT_TYPE, filter);
}
/**
* Wraps the filter in FilterImpl
*
* @param path the path
* @param acceptType the accept type
* @param filter the filter
* @return the wrapped route
*/
protected static FilterImpl wrap(final String path, String acceptType, final Filter filter) {
if (acceptType == null) {
acceptType = DEFAULT_ACCEPT_TYPE;
}
FilterImpl impl = new FilterImpl(path, acceptType) {
@Override
public void handle(Request request, Response response) throws Exception {
filter.handle(request, response);
}
};
return impl;
}
protected static void addRoute(String httpMethod, RouteImpl route) {
init();
routeMatcher.parseValidateAddRoute(httpMethod + " '" + route.getPath()
+ "'", route.getAcceptType(), route);
}
protected static void addFilter(String httpMethod, FilterImpl filter) {
init();
routeMatcher.parseValidateAddRoute(httpMethod + " '" + filter.getPath()
+ "'", filter.getAcceptType(), filter);
}
private static synchronized void init() {
if (!initialized) {
routeMatcher = RouteMatcherFactory.get();
new Thread(new Runnable() {
@Override
public void run() {
server = SparkServerFactory.create(hasMultipleHandlers());
server.ignite(
ipAddress,
port,
keystoreFile,
keystorePassword,
truststoreFile,
truststorePassword,
staticFileFolder,
externalStaticFileFolder);
}
}).start();
initialized = true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment