Skip to content

Commit

Permalink
wrap ServerSentEventHandler class
Browse files Browse the repository at this point in the history
  • Loading branch information
granny committed Apr 12, 2024
1 parent 20d1ad9 commit ade62c7
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 38 deletions.
39 changes: 9 additions & 30 deletions core/src/main/java/net/pl3x/map/core/httpd/HttpdServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
import io.undertow.server.handlers.resource.PathResourceManager;
import io.undertow.server.handlers.resource.ResourceHandler;
import io.undertow.server.handlers.resource.ResourceManager;
import io.undertow.server.handlers.sse.ServerSentEventConnection;
import io.undertow.server.handlers.sse.ServerSentEventHandler;
import io.undertow.util.ETag;
import io.undertow.util.Headers;
import io.undertow.util.HttpString;
Expand All @@ -54,30 +52,10 @@
public class HttpdServer {
private HttpString X_ACCEL_BUFFERING = new HttpString("X-Accel-Buffering");
private Undertow server;
private ServerSentEventHandler serverSentEventHandler = Handlers.serverSentEvents();
private LiveDataHandler liveDataHandler = new LiveDataHandler();

public void sendSSE(ServerSentEventHandler serverSentEventHandler, String event, String data) {
for (ServerSentEventConnection connection : serverSentEventHandler.getConnections()) {
connection.send(data, event, null, null);
}
}

public void sendSSE(ServerSentEventHandler serverSentEventHandler, String data) {
sendSSE(serverSentEventHandler, null, data);
}

public void sendSSE(String event, String data) {
sendSSE(this.serverSentEventHandler, event, data);
}

public void sendSSE(String data) {
sendSSE(this.serverSentEventHandler, null, data);
}

public void closeSSEConnections(ServerSentEventHandler serverSentEventHandler) {
for (ServerSentEventConnection connection : serverSentEventHandler.getConnections()) {
connection.shutdown();
}
public LiveDataHandler getLiveDataHandler() {
return liveDataHandler;
}

public void startServer() {
Expand Down Expand Up @@ -134,7 +112,7 @@ public void startServer() {
String worldName = exchange.getQueryParameters().get("world").peek();
if (worldName == null || worldName.isEmpty()) {
exchange.getResponseHeaders().put(X_ACCEL_BUFFERING, "no");
serverSentEventHandler.handleRequest(exchange);
liveDataHandler.handle(exchange);
return;
}

Expand All @@ -146,14 +124,15 @@ public void startServer() {
.map(World::getName).collect(Collectors.joining(", "));
handleError(exchange, "Could not find world named '%s'. Available worlds: %s"
.formatted(worldName, listOfValidWorlds));
exchange.endExchange();
return;
}

if (exchange.isInIoThread()) {
exchange.dispatch(world.getServerSentEventHandler());
exchange.dispatch(world.getServerSentEventHandler().get());
} else {
exchange.getResponseHeaders().put(X_ACCEL_BUFFERING, "no");
world.getServerSentEventHandler().handleRequest(exchange);
world.getServerSentEventHandler().handle(exchange);
}
})
)
Expand Down Expand Up @@ -189,9 +168,9 @@ public void stopServer() {
}

LogFilter.HIDE_UNDERTOW_LOGS = true;
this.closeSSEConnections(this.serverSentEventHandler);
this.liveDataHandler.closeConnections();
Pl3xMap.api().getWorldRegistry().forEach(world -> {
this.closeSSEConnections(world.getServerSentEventHandler());
world.getServerSentEventHandler().closeConnections();
});
this.server.stop();
LogFilter.HIDE_UNDERTOW_LOGS = false;
Expand Down
150 changes: 150 additions & 0 deletions core/src/main/java/net/pl3x/map/core/httpd/LiveDataHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* MIT License
*
* Copyright (c) 2020-2023 William Blake Galbreath
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.pl3x.map.core.httpd;

import io.undertow.Handlers;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.sse.ServerSentEventConnection;
import io.undertow.server.handlers.sse.ServerSentEventHandler;
import java.io.IOException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class LiveDataHandler {
private ServerSentEventHandler serverSentEventHandler;

public LiveDataHandler() {
this.serverSentEventHandler = Handlers.serverSentEvents();
}

/**
*
* @param event The message event
* @param data The message data
* @param success The callback that is called when a message is sucessfully sent.
* @param failure The callback that is called when a message send fails.
*/
public void send(String event, String data, SuccessCallback success, FailureCallback failure) {
if (serverSentEventHandler == null) {
return;
}

Callback callback = new Callback(success, failure);
for (ServerSentEventConnection connection : this.serverSentEventHandler.getConnections()) {
connection.send(data, event, null, callback);
}
}

/**
*
* @param event The message event
* @param data The message data
* @param success The callback that is called when a message is sucessfully sent.
*/
public void send(String event, String data, SuccessCallback success) {
this.send(event, data, success, null);
}

/**
*
* @param event The message event
* @param data The message data
*/
public void send(String event, String data) {
this.send(event, data, null, null);
}

/**
*
* @param data The message data
*/
public void send(String data) {
this.send(null, data);
}

public void closeConnections() {
for (ServerSentEventConnection connection : serverSentEventHandler.getConnections()) {
connection.shutdown();
}
}

public void handle(HttpServerExchange exchange) throws Exception {
this.serverSentEventHandler.handleRequest(exchange);
}

public ServerSentEventHandler get() {
return this.serverSentEventHandler;
}

/**
* Notification that is called when a message is sucessfully sent
*/
public interface SuccessCallback {
/**
* @param connection The connection
* @param data The message data
* @param event The message event
* @param id The message id
*/
void apply(@NotNull ServerSentEventConnection connection, @Nullable String data, @Nullable String event, @Nullable String id);
}

/**
* Notification that is called when a message send fails.
*/
public interface FailureCallback {
/**
* @param connection The connection
* @param data The message data
* @param event The message event
* @param id The message id
* @param exception The exception
*/
void apply(@NotNull ServerSentEventConnection connection, @Nullable String data, @Nullable String event, @Nullable String id, @NotNull IOException exception);
}

private class Callback implements ServerSentEventConnection.EventCallback {
private SuccessCallback success;
private FailureCallback failure;

public Callback(SuccessCallback success, FailureCallback failure) {
this.success = success;
this.failure = failure;
}

@Override
public void done(ServerSentEventConnection connection, String data, String event, String id) {
if (success != null) {
success.apply(connection, data, event, id);
}
}

@Override
public void failed(ServerSentEventConnection connection, String data, String event, String id, IOException e) {
if (failure != null) {
failure.apply(connection, data, event, id, e);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public void parse() {
int markerHashCode = list.hashCode();
if (markerCacheIfPresent == null || !markerCacheIfPresent.equals(markerHashCode)) {
Logger.debug("[%s/%s] sending through sse %d".formatted(this.world.getName(), key, (System.currentTimeMillis())));
Pl3xMap.api().getHttpdServer().sendSSE(world.getServerSentEventHandler(), "markers", String.format("{\"key\": \"%s\", \"markers\": %s}", key, this.gson.toJson(list)));
world.getServerSentEventHandler().send("markers", String.format("{\"key\": \"%s\", \"markers\": %s}", key, this.gson.toJson(list)));
markerCache.put(key, markerHashCode);
}
} catch (Throwable t) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ private void parseSettings() {
String json = this.gson.toJson(map);

if (jsonHashCache != json.hashCode()) {
Pl3xMap.api().getHttpdServer().sendSSE("settings", json);
Pl3xMap.api().getHttpdServer().getLiveDataHandler().send("settings", json);
jsonHashCache = json.hashCode();
}

Expand Down
13 changes: 7 additions & 6 deletions core/src/main/java/net/pl3x/map/core/world/World.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import io.undertow.Handlers;
import io.undertow.server.handlers.sse.ServerSentEventHandler;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
Expand All @@ -48,6 +46,7 @@
import net.pl3x.map.core.configuration.SpawnLayerConfig;
import net.pl3x.map.core.configuration.WorldBorderLayerConfig;
import net.pl3x.map.core.configuration.WorldConfig;
import net.pl3x.map.core.httpd.LiveDataHandler;
import net.pl3x.map.core.image.IconImage;
import net.pl3x.map.core.log.Logger;
import net.pl3x.map.core.markers.Point;
Expand Down Expand Up @@ -82,7 +81,8 @@ public abstract class World extends Keyed {
private final long seed;
private final Point spawn;
private final Type type;
private final ServerSentEventHandler serverSentEventHandler;

private final LiveDataHandler liveDataHandler;

private final BiomeManager biomeManager;
private final BiomeRegistry biomeRegistry;
Expand All @@ -101,7 +101,8 @@ public World(@NotNull String name, long seed, @NotNull Point spawn, @NotNull Typ
this.seed = seed;
this.spawn = spawn;
this.type = type;
this.serverSentEventHandler = Handlers.serverSentEvents();

this.liveDataHandler = new LiveDataHandler();

String safeNameForDirectories = name.replace(":", "-");

Expand Down Expand Up @@ -266,8 +267,8 @@ public int getSkylight() {
return this.type;
}

public ServerSentEventHandler getServerSentEventHandler() {
return serverSentEventHandler;
public LiveDataHandler getServerSentEventHandler() {
return liveDataHandler;
}

public @NotNull BiomeManager getBiomeManager() {
Expand Down

0 comments on commit ade62c7

Please sign in to comment.