From ebee6a9d4cd332364e079b56438f718f90a7b0bd Mon Sep 17 00:00:00 2001 From: Iliyan Velichkov Date: Mon, 22 Jun 2026 09:47:10 +0300 Subject: [PATCH 1/2] Add Spring-style websocket examples (interface + @OnX method-level) Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 8 +++++ .../demo/websocket/EchoHandler.java | 22 ++++++++++++++ .../demo/websocket/TickerHandler.java | 29 +++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 sample-java-websocket-decorator/demo/websocket/EchoHandler.java create mode 100644 sample-java-websocket-decorator/demo/websocket/TickerHandler.java diff --git a/README.md b/README.md index 79c8788..6b05255 100644 --- a/README.md +++ b/README.md @@ -24,3 +24,11 @@ GET /services/java/sample-java-websocket-decorator/demo/websocket/WebsocketStatu ``` Returns `{"registered": true}` when the `"java-chat"` endpoint is active. + +## Websocket styles + +- **Reflective** — `ChatHandler` (an `@Websocket` class with `onOpen`/`onMessage`/… by name). +- **Strong interface** — `EchoHandler implements WebsocketHandler` (override only what you need). +- **Method-level annotations** — `TickerHandler` with `@OnOpen`/`@OnMessage`/`@OnClose`. + +See the [Develop guide](https://www.dirigible.io/help/develop/websockets/) and the [Java SDK](https://www.dirigible.io/sdk/). diff --git a/sample-java-websocket-decorator/demo/websocket/EchoHandler.java b/sample-java-websocket-decorator/demo/websocket/EchoHandler.java new file mode 100644 index 0000000..9d34db7 --- /dev/null +++ b/sample-java-websocket-decorator/demo/websocket/EchoHandler.java @@ -0,0 +1,22 @@ +package demo.websocket; + +import org.eclipse.dirigible.sdk.net.Websocket; +import org.eclipse.dirigible.sdk.net.WebsocketHandler; + +/** + * Strong-interface websocket style: implement WebsocketHandler and override only the callbacks you + * need — the rest default to no-ops. + */ +@Websocket(name = "Java Echo", endpoint = "java-echo") +public class EchoHandler implements WebsocketHandler { + + @Override + public void onOpen() { + System.out.println("EchoHandler: client connected"); + } + + @Override + public void onMessage(String message, String from) { + System.out.println("EchoHandler (" + from + "): " + message); + } +} diff --git a/sample-java-websocket-decorator/demo/websocket/TickerHandler.java b/sample-java-websocket-decorator/demo/websocket/TickerHandler.java new file mode 100644 index 0000000..17614bd --- /dev/null +++ b/sample-java-websocket-decorator/demo/websocket/TickerHandler.java @@ -0,0 +1,29 @@ +package demo.websocket; + +import org.eclipse.dirigible.sdk.net.OnClose; +import org.eclipse.dirigible.sdk.net.OnMessage; +import org.eclipse.dirigible.sdk.net.OnOpen; +import org.eclipse.dirigible.sdk.net.Websocket; + +/** + * Method-level callback style (Jakarta-WebSocket flavour): annotate methods with @OnOpen / @OnMessage / + * @OnClose. A non-void @OnMessage return value is sent back to the client. + */ +@Websocket(name = "Java Ticker", endpoint = "java-ticker") +public class TickerHandler { + + @OnOpen + public void opened() { + System.out.println("TickerHandler: client connected"); + } + + @OnMessage + public String message(String message, String from) { + return "tick: " + message; + } + + @OnClose + public void closed() { + System.out.println("TickerHandler: client disconnected"); + } +} From a77fcb9a25b0e1ab2654d2c506102130998c7924 Mon Sep 17 00:00:00 2001 From: Iliyan Velichkov Date: Mon, 22 Jun 2026 10:40:51 +0300 Subject: [PATCH 2/2] Use the two clean styles: self-describing WebsocketHandler + @OnX annotation style Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 7 +++-- .../demo/websocket/ChatHandler.java | 28 +++++++++++-------- .../demo/websocket/EchoHandler.java | 22 --------------- 3 files changed, 21 insertions(+), 36 deletions(-) delete mode 100644 sample-java-websocket-decorator/demo/websocket/EchoHandler.java diff --git a/README.md b/README.md index 6b05255..3c54b67 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,9 @@ Returns `{"registered": true}` when the `"java-chat"` endpoint is active. ## Websocket styles -- **Reflective** — `ChatHandler` (an `@Websocket` class with `onOpen`/`onMessage`/… by name). -- **Strong interface** — `EchoHandler implements WebsocketHandler` (override only what you need). -- **Method-level annotations** — `TickerHandler` with `@OnOpen`/`@OnMessage`/`@OnClose`. +Two ways to write a Java WebSocket handler — pick one per `@Component` class (never both), like Spring: + +- **Strong interface** — `ChatHandler` is a `@Component` that implements `WebsocketHandler` and supplies its own `endpoint()` (like `TextWebSocketHandler`); no `@Websocket` annotation. +- **Method-level annotations** — `TickerHandler` is a `@Websocket(endpoint = …)` class with `@OnOpen`/`@OnMessage`/`@OnClose` methods (Jakarta `@ServerEndpoint` style — the endpoint has no method-level home). See the [Develop guide](https://www.dirigible.io/help/develop/websockets/) and the [Java SDK](https://www.dirigible.io/sdk/). diff --git a/sample-java-websocket-decorator/demo/websocket/ChatHandler.java b/sample-java-websocket-decorator/demo/websocket/ChatHandler.java index 1d9db18..1c3c062 100644 --- a/sample-java-websocket-decorator/demo/websocket/ChatHandler.java +++ b/sample-java-websocket-decorator/demo/websocket/ChatHandler.java @@ -1,35 +1,41 @@ package demo.websocket; -import org.eclipse.dirigible.sdk.net.Websocket; +import org.eclipse.dirigible.sdk.component.Component; +import org.eclipse.dirigible.sdk.net.WebsocketHandler; /** - * Demonstrates {@code @Websocket}: registers this class as the handler for the - * {@code "java-chat"} WebSocket endpoint. Clients connect via - * {@code ws:///websockets/stomp/java-chat}. - * - *

- * All four lifecycle methods are shown; any subset is valid — missing methods are silently skipped - * by the runtime. + * Strong-interface websocket style: a {@code @Component} that implements {@link WebsocketHandler} + * and supplies its own endpoint — no {@code @Websocket} annotation. Clients connect via + * {@code ws:///websockets/stomp/java-chat}. Override only the callbacks you need; the rest + * inherit the no-op default. */ -@Websocket(name = "Java Chat", endpoint = "java-chat") -public class ChatHandler { +@Component +public class ChatHandler implements WebsocketHandler { static final String ENDPOINT = "java-chat"; + @Override + public String endpoint() { + return ENDPOINT; + } + + @Override public void onOpen() { System.out.println("ChatHandler: client connected"); } + @Override public void onMessage(String message, String from) { System.out.println("ChatHandler: " + from + " says: " + message); } + @Override public void onError(String error) { System.out.println("ChatHandler: error: " + error); } + @Override public void onClose() { System.out.println("ChatHandler: client disconnected"); } - } diff --git a/sample-java-websocket-decorator/demo/websocket/EchoHandler.java b/sample-java-websocket-decorator/demo/websocket/EchoHandler.java deleted file mode 100644 index 9d34db7..0000000 --- a/sample-java-websocket-decorator/demo/websocket/EchoHandler.java +++ /dev/null @@ -1,22 +0,0 @@ -package demo.websocket; - -import org.eclipse.dirigible.sdk.net.Websocket; -import org.eclipse.dirigible.sdk.net.WebsocketHandler; - -/** - * Strong-interface websocket style: implement WebsocketHandler and override only the callbacks you - * need — the rest default to no-ops. - */ -@Websocket(name = "Java Echo", endpoint = "java-echo") -public class EchoHandler implements WebsocketHandler { - - @Override - public void onOpen() { - System.out.println("EchoHandler: client connected"); - } - - @Override - public void onMessage(String message, String from) { - System.out.println("EchoHandler (" + from + "): " + message); - } -}