Skip to content

Commit

Permalink
Merge pull request #119 from 12urenloop/ws-endpoint
Browse files Browse the repository at this point in the history
WebSocket endpoint
  • Loading branch information
Topvennie authored Mar 29, 2024
2 parents 8f9e453 + 5d42686 commit b65020a
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 3 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ sourceCompatibility = 17
// Set our project variables
project.ext {
dropwizardVersion = '4.0.5'
jettyVersion = '11.0.19'
}

repositories {
Expand Down Expand Up @@ -62,6 +63,8 @@ dependencies {
'io.dropwizard:dropwizard-hibernate:' + dropwizardVersion,
'io.dropwizard:dropwizard-auth:' + dropwizardVersion,
'io.dropwizard:dropwizard-jdbi3:' + dropwizardVersion,
'org.eclipse.jetty.websocket:websocket-jetty-api:' + jettyVersion,
'org.eclipse.jetty.websocket:websocket-jetty-server:' + jettyVersion,
)
// Database
implementation('com.h2database:h2:2.2.220')
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/telraam/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import jakarta.servlet.DispatcherType;
import jakarta.servlet.FilterRegistration;
import org.eclipse.jetty.servlets.CrossOriginFilter;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.jdbi.v3.core.Jdbi;
import telraam.api.*;
import telraam.database.daos.*;
Expand All @@ -21,6 +22,7 @@
import telraam.logic.robust.RobustLapper;
import telraam.station.Fetcher;
import telraam.util.AcceptedLapsUtil;
import telraam.websocket.WebSocketConnection;

import java.io.IOException;
import java.util.EnumSet;
Expand Down Expand Up @@ -78,6 +80,15 @@ public void run(AppConfiguration configuration, Environment environment) throws
// Initialize AcceptedLapUtil
AcceptedLapsUtil.createInstance(this.database);

// Register websocket endpoint
JettyWebSocketServletContainerInitializer.configure(
environment.getApplicationContext(),
(servletContext, wsContainer) -> {
wsContainer.setMaxTextMessageSize(65535);
wsContainer.addMapping("/ws", (req, res) -> new WebSocketConnection());
}
);

// Add api resources
JerseyEnvironment jersey = environment.jersey();
jersey.register(new BatonResource(database.onDemand(BatonDAO.class)));
Expand All @@ -94,7 +105,6 @@ public void run(AppConfiguration configuration, Environment environment) throws
jersey.register(new MonitoringResource(database));
environment.healthChecks().register("template", new TemplateHealthCheck(configuration.getTemplate()));


// Enable CORS
final FilterRegistration.Dynamic cors = environment.servlets().addFilter("CORS", CrossOriginFilter.class);

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/telraam/api/TeamResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import telraam.database.daos.BatonSwitchoverDAO;
import telraam.database.daos.TeamDAO;
import telraam.database.models.BatonSwitchover;
import telraam.database.models.Team;

import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.MediaType;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.List;
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/telraam/websocket/WebSocketConnection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package telraam.websocket;

import java.io.IOException;
import java.util.logging.Logger;

import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;

public class WebSocketConnection extends WebSocketAdapter {
private static final Logger logger = Logger.getLogger(WebSocketConnection.class.getName());

@Override
public void onWebSocketConnect(Session session) {
super.onWebSocketConnect(session);
WebSocketMessageSingleton.getInstance().registerConnection(this);
logger.info("Instance with remote \"%s\" connected".formatted(getRemote().getRemoteAddress()));
}

@Override
public void onWebSocketClose(int statusCode, String reason) {
super.onWebSocketClose(statusCode, reason);
WebSocketMessageSingleton.getInstance().unregisterConnection(this);
logger.info("Instance with remote \"%s\" closed: [%s] %s".formatted(getRemote().getRemoteAddress(), statusCode, reason));
}

@Override
public void onWebSocketError(Throwable cause) {
super.onWebSocketError(cause);
logger.severe("WebSocket error in instance with remote \"%s\": %s".formatted(getRemote().getRemoteAddress(), cause));
}

public void send(String s) {
try {
getRemote().sendString(s);
} catch (IOException e) {
logger.severe("Sending \"%s\" through instance with remote \"%s\" failed with %s".formatted(s, getRemote().getRemoteAddress(), e));
return;
}
logger.finest("Sent \"%s\" through instance with remote \"%s\"".formatted(s, getRemote().getRemoteAddress()));
}
}
37 changes: 37 additions & 0 deletions src/main/java/telraam/websocket/WebSocketMessageSingleton.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package telraam.websocket;

import lombok.Getter;

import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;

public class WebSocketMessageSingleton {
private static final Logger logger = Logger.getLogger(WebSocketMessageSingleton.class.getName());

@Getter
private static final WebSocketMessageSingleton instance = new WebSocketMessageSingleton();
private static final Set<WebSocketConnection> registeredConnections = new HashSet<>();

private WebSocketMessageSingleton() {
}

public void registerConnection(WebSocketConnection conn) {
boolean modified = registeredConnections.add(conn);
if (modified) {
logger.info("Registered WebSocketConnection %s".formatted(conn));
}
}

public void unregisterConnection(WebSocketConnection conn) {
boolean modified = registeredConnections.remove(conn);
if (modified) {
logger.info("Unregistered WebSocketConnection %s".formatted(conn));
}
}

public void sendToAll(String s) {
logger.finest("Sending \"%s\" to all registered WebSocketConnection instances".formatted(s));
registeredConnections.forEach(conn -> conn.send(s));
}
}

0 comments on commit b65020a

Please sign in to comment.