@@ -140,30 +140,61 @@ sprout:
140140
141141---
142142
143- # # 🔌 WebSocket Example (NIO)
143+ # # 🎥 WebSocket Demo & Benchmark
144144
145+ [](https://www.youtube.com/watch?v=7ypz7RCcZps)
146+
147+ This video demonstrates Sprout’s **fully non-blocking NIO WebSocket stack** in action.
148+
149+ **What’s shown in the demo:**
150+ - NIO-based WebSocket handshake & frame processing
151+ - Concurrent client connections
152+ - Echo, broadcast, chat-style messaging
153+ - Ping/Pong frames
154+ - Graceful close handling
155+ - Non-blocking write queue with OP_WRITE toggling
156+
157+ The handler used in the video is a real application-level WebSocket handler built on Sprout’s APIs (see below).
158+
159+ ---
160+
161+ # # 🧩 WebSocket Example
145162` ` ` java
146- @WebSocketEndpoint("/ws/chat")
147- public class ChatSocket {
163+ @Component
164+ @WebSocketHandler("/ws/benchmark")
165+ public class WebSocketBenchmarkHandler {
166+
167+ private static final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
148168
149169 @OnOpen
150170 public void onOpen(WebSocketSession session) {
151- System.out.println("WebSocket opened: " + session.getId());
171+ sessions.put( session.getId(), session );
152172 }
153173
154- @MessageMapping("/chat.send")
155- public void handleMessage (WebSocketSession session, @RequestBody ChatMessage msg ) {
156- System.out.println("Message from " + session.getId() + ": " + msg.getText ());
174+ @OnClose
175+ public void onClose (WebSocketSession session, CloseCode code ) {
176+ sessions.remove( session.getId());
157177 }
158178
159- @OnClose
160- public void onClose(WebSocketSession session) {
161- System.out.println("WebSocket closed: " + session.getId());
179+ @MessageMapping("/echo")
180+ public void echo(WebSocketSession session, @Payload String msg) throws IOException {
181+ session.sendText(msg);
182+ }
183+
184+ @MessageMapping("/broadcast")
185+ public void broadcast(WebSocketSession session, @Payload String msg) throws IOException {
186+ for (WebSocketSession s : sessions.values()) {
187+ if (s.isOpen()) s.sendText(msg);
188+ }
189+ }
190+
191+ @MessageMapping("/ping")
192+ public void ping(WebSocketSession session, @Payload String ignored) throws IOException {
193+ session.sendPing("ping".getBytes());
162194 }
163195}
164196` ` `
165-
166- **Annotations such as `@WebSocketEndpoint` and `@MessageMapping` are provided by Sprout (not JSR-356).**
197+ > Runs on Sprout’s NIO selector loop with non-blocking writes and frame-level control.
167198
168199---
169200
@@ -195,7 +226,7 @@ Tooling & style:
195226* Selector/`interestOps` state fakes to validate NIO behavior without real sockets
196227* Build report: `build/reports/tests/test/index.html`
197228
198- > Want to help? Add black-box integration tests that spin up the NIO server and hit it with a real HTTP/WebSocket client.
229+ ---
199230
200231# # 🗺️ Roadmap
201232
0 commit comments