Skip to content

Commit 96efaab

Browse files
committed
docs: update README.md
1 parent 00755cb commit 96efaab

2 files changed

Lines changed: 143 additions & 83 deletions

File tree

README.md

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -140,30 +140,61 @@ sprout:
140140

141141
---
142142

143-
## 🔌 WebSocket Example (NIO)
143+
## 🎥 WebSocket Demo & Benchmark
144144

145+
[![Sprout WebSocket Demo](https://img.youtube.com/vi/7ypz7RCcZps/0.jpg)](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

Comments
 (0)