1package dev.rafex.ether.websocket.jetty12;
29import java.nio.ByteBuffer;
30import java.util.Collections;
31import java.util.LinkedHashMap;
34import java.util.Objects;
35import java.util.concurrent.CompletableFuture;
36import java.util.concurrent.CompletionStage;
37import java.util.concurrent.ConcurrentHashMap;
39import org.eclipse.jetty.websocket.api.Callback;
40import org.eclipse.jetty.websocket.api.Session;
42import dev.rafex.ether.websocket.core.WebSocketCloseStatus;
43import dev.rafex.ether.websocket.core.WebSocketSession;
55 private final Session session;
56 private final String path;
57 private final Map<String, String> pathParams;
58 private final Map<String, List<String>> queryParams;
59 private final Map<String, List<String>> headers;
60 private final Map<String, Object> attributes =
new ConcurrentHashMap<>();
73 final Map<String, List<String>> queryParams,
final Map<String, List<String>> headers) {
74 this.session = Objects.requireNonNull(session,
"session");
75 this.path = Objects.requireNonNull(path,
"path");
76 this.pathParams = Map.copyOf(pathParams);
77 this.queryParams = copyMultiMap(queryParams);
78 this.headers = copyMultiMap(headers);
89 return Integer.toHexString(System.identityHashCode(session));
109 final var protocol = session.getUpgradeResponse() ==
null ? null
110 : session.getUpgradeResponse().getAcceptedSubProtocol();
111 return protocol ==
null ?
"" : protocol;
121 return session.isOpen();
132 return pathParams.get(name);
143 final var values = queryParams.get(name);
144 if (values ==
null || values.isEmpty()) {
147 return values.get(0);
158 return queryParams.getOrDefault(name, List.of());
169 final var values = headers.get(name);
170 if (values ==
null || values.isEmpty()) {
173 return values.get(0);
184 return attributes.get(name);
196 public void attribute(
final String name,
final Object value) {
198 attributes.remove(name);
201 attributes.put(name, value);
241 public CompletionStage<Void>
sendText(
final String text) {
242 final var future =
new CompletableFuture<Void>();
243 session.sendText(text, callbackOf(future));
254 public CompletionStage<Void>
sendBinary(
final ByteBuffer data) {
255 final var future =
new CompletableFuture<Void>();
256 session.sendBinary(data ==
null ? ByteBuffer.allocate(0) : data.slice(), callbackOf(future));
267 public CompletionStage<Void>
close(
final WebSocketCloseStatus status) {
268 final var future =
new CompletableFuture<Void>();
269 final var closeStatus = status ==
null ? WebSocketCloseStatus.NORMAL : status;
270 session.close(closeStatus.code(), closeStatus.reason(), callbackOf(future));
280 private static Callback callbackOf(
final CompletableFuture<Void> future) {
281 return Callback.from(() -> future.complete(
null), future::completeExceptionally);
290 private static Map<String, List<String>> copyMultiMap(
final Map<String, List<String>> input) {
291 final var out =
new LinkedHashMap<String, List<String>>();
293 for (
final var entry : input.entrySet()) {
294 out.put(entry.getKey(), entry.getValue() ==
null ? List.of() : List.copyOf(entry.getValue()));
297 return Collections.unmodifiableMap(out);
List< String > queryAll(final String name)
Returns all values of a query parameter.
boolean isOpen()
Returns whether the underlying session is still open.
CompletionStage< Void > sendBinary(final ByteBuffer data)
Sends a binary message asynchronously.
CompletionStage< Void > close(final WebSocketCloseStatus status)
Closes the session with the given status code and reason.
CompletionStage< Void > sendText(final String text)
Sends a text message asynchronously.
Map< String, String > pathParams()
Returns an unmodifiable view of all path parameters.
Object attribute(final String name)
Returns a session-scoped attribute by name.
String path()
Returns the matched request path.
String subprotocol()
Returns the accepted subprotocol, or an empty string if none was negotiated.
String pathParam(final String name)
Returns the value of a single path parameter by name.
Map< String, List< String > > queryParams()
Returns an unmodifiable view of all query parameters.
JettyWebSocketSession(final Session session, final String path, final Map< String, String > pathParams, final Map< String, List< String > > queryParams, final Map< String, List< String > > headers)
Creates a session wrapper.
String queryFirst(final String name)
Returns the first value of a query parameter.
void attribute(final String name, final Object value)
Sets or removes a session-scoped attribute.
Map< String, List< String > > headers()
Returns an unmodifiable view of all HTTP headers.
String headerFirst(final String name)
Returns the first value of an HTTP header.
String id()
Returns a unique session identifier derived from the native session's identity hash code.
Representa una sesión WebSocket activa.