Add WebSocket support with routing, origin validation, session management, and broadcasting
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
package dev.coph.nextusweb.server.websocket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public final class WebSocketRouter {
|
||||
|
||||
private final Node root = new Node();
|
||||
|
||||
public WebSocketRouter on(String path, WebSocketHandler handler) {
|
||||
Node node = root;
|
||||
for (String segment : split(path)) {
|
||||
if (segment.startsWith("{") && segment.endsWith("}")) {
|
||||
if (node.paramChild == null) {
|
||||
node.paramChild = new Node();
|
||||
node.paramName = segment.substring(1, segment.length() - 1);
|
||||
}
|
||||
node = node.paramChild;
|
||||
} else {
|
||||
node = node.children.computeIfAbsent(segment, k -> new Node());
|
||||
}
|
||||
}
|
||||
node.handler = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Resolution resolve(String path) {
|
||||
Map<String, String> params = new HashMap<>(4);
|
||||
Node node = root;
|
||||
for (String segment : split(path)) {
|
||||
Node next = node.children.get(segment);
|
||||
if (next != null) {
|
||||
node = next;
|
||||
} else if (node.paramChild != null) {
|
||||
params.put(node.paramName, segment);
|
||||
node = node.paramChild;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (node.handler == null) return null;
|
||||
return new Resolution(node.handler, params);
|
||||
}
|
||||
|
||||
private static List<String> split(String path) {
|
||||
List<String> out = new ArrayList<>();
|
||||
int start = path.startsWith("/") ? 1 : 0;
|
||||
for (int i = start; i < path.length(); i++) {
|
||||
if (path.charAt(i) == '/') {
|
||||
if (i > start) out.add(path.substring(start, i));
|
||||
start = i + 1;
|
||||
}
|
||||
}
|
||||
if (start < path.length()) out.add(path.substring(start));
|
||||
return out;
|
||||
}
|
||||
|
||||
public record Resolution(WebSocketHandler handler, Map<String, String> pathParams) {
|
||||
}
|
||||
|
||||
private static final class Node {
|
||||
final Map<String, Node> children = new ConcurrentHashMap<>();
|
||||
Node paramChild;
|
||||
String paramName;
|
||||
WebSocketHandler handler;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user