or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdbroadcasting.mdcaching.mdcore-framework.mdindex.mdinterceptors.mdwebsocket.md

websocket.mddocs/

0

# WebSocket Support

1

2

Complete WebSocket integration including connection management, protocol handling, message processing, and custom protocol implementations. Atmosphere provides full WebSocket support with fallback capabilities.

3

4

## Capabilities

5

6

### WebSocket Interface

7

8

Core WebSocket connection abstraction providing methods for communication and connection management.

9

10

```java { .api }

11

/**

12

* WebSocket connection abstraction

13

*/

14

public interface WebSocket {

15

/**

16

* Write string data to WebSocket

17

* @param data string data to send

18

* @return this WebSocket for chaining

19

*/

20

public WebSocket write(String data);

21

22

/**

23

* Write byte array data to WebSocket

24

* @param data byte array to send

25

* @return this WebSocket for chaining

26

*/

27

public WebSocket write(byte[] data);

28

29

/**

30

* Write generic object data (will be serialized)

31

* @param data object to send

32

* @return this WebSocket for chaining

33

*/

34

public WebSocket write(Object data);

35

36

/**

37

* Close the WebSocket connection

38

*/

39

public void close();

40

41

/**

42

* Close with specific code and reason

43

* @param closeCode WebSocket close code

44

* @param message close reason message

45

*/

46

public void close(int closeCode, String message);

47

48

/**

49

* Check if WebSocket is open and ready

50

* @return true if connection is open

51

*/

52

public boolean isOpen();

53

54

/**

55

* Get the associated AtmosphereResource

56

* @return AtmosphereResource instance

57

*/

58

public AtmosphereResource resource();

59

}

60

```

61

62

**Usage Examples:**

63

64

```java

65

public class ChatWebSocketHandler implements WebSocketHandler {

66

@Override

67

public void onOpen(WebSocket webSocket) {

68

System.out.println("WebSocket opened");

69

webSocket.write("Welcome to chat!");

70

}

71

72

@Override

73

public void onTextMessage(WebSocket webSocket, String message) {

74

// Echo message back

75

webSocket.write("Echo: " + message);

76

77

// Broadcast to all connected clients

78

webSocket.resource().getBroadcaster().broadcast(message);

79

}

80

81

@Override

82

public void onClose(WebSocket webSocket) {

83

System.out.println("WebSocket closed");

84

}

85

}

86

```

87

88

### WebSocketHandler Interface

89

90

Event handler interface for managing WebSocket lifecycle events and message processing.

91

92

```java { .api }

93

/**

94

* Handle WebSocket-specific events and messages

95

*/

96

public interface WebSocketHandler {

97

/**

98

* Called when WebSocket connection is opened

99

* @param webSocket the opened WebSocket

100

*/

101

public void onOpen(WebSocket webSocket);

102

103

/**

104

* Called when WebSocket connection is closed

105

* @param webSocket the closed WebSocket

106

*/

107

public void onClose(WebSocket webSocket);

108

109

/**

110

* Called when WebSocket connection encounters an error

111

* @param webSocket the WebSocket with error

112

* @param t the error that occurred

113

*/

114

public void onError(WebSocket webSocket, Throwable t);

115

116

/**

117

* Called when text message is received

118

* @param webSocket the receiving WebSocket

119

* @param message the text message received

120

*/

121

public void onTextMessage(WebSocket webSocket, String message);

122

123

/**

124

* Called when binary message is received

125

* @param webSocket the receiving WebSocket

126

* @param message the binary message as byte array

127

*/

128

public void onByteMessage(WebSocket webSocket, byte[] message);

129

}

130

```

131

132

**Usage Examples:**

133

134

```java

135

@WebSocketHandlerService(path = "/websocket/data")

136

public class DataWebSocketHandler implements WebSocketHandler {

137

138

@Override

139

public void onOpen(WebSocket webSocket) {

140

// Send initial data when client connects

141

webSocket.write("{\"type\":\"welcome\",\"message\":\"Connected\"}");

142

143

// Add to broadcaster for group messages

144

webSocket.resource().getBroadcaster()

145

.addAtmosphereResource(webSocket.resource());

146

}

147

148

@Override

149

public void onTextMessage(WebSocket webSocket, String message) {

150

try {

151

// Parse JSON message

152

JsonObject json = JsonParser.parseString(message).getAsJsonObject();

153

String type = json.get("type").getAsString();

154

155

switch (type) {

156

case "ping":

157

webSocket.write("{\"type\":\"pong\"}");

158

break;

159

case "broadcast":

160

String msg = json.get("message").getAsString();

161

webSocket.resource().getBroadcaster().broadcast(msg);

162

break;

163

default:

164

webSocket.write("{\"type\":\"error\",\"message\":\"Unknown type\"}");

165

}

166

} catch (Exception e) {

167

webSocket.write("{\"type\":\"error\",\"message\":\"Invalid JSON\"}");

168

}

169

}

170

171

@Override

172

public void onByteMessage(WebSocket webSocket, byte[] message) {

173

// Handle binary data (e.g., file uploads, images)

174

System.out.println("Received " + message.length + " bytes");

175

176

// Echo binary data back

177

webSocket.write(message);

178

}

179

180

@Override

181

public void onClose(WebSocket webSocket) {

182

// Cleanup when client disconnects

183

webSocket.resource().getBroadcaster()

184

.removeAtmosphereResource(webSocket.resource());

185

System.out.println("WebSocket closed for: " + webSocket.resource().uuid());

186

}

187

188

@Override

189

public void onError(WebSocket webSocket, Throwable t) {

190

System.err.println("WebSocket error: " + t.getMessage());

191

t.printStackTrace();

192

}

193

}

194

```

195

196

### WebSocketProcessor Interface

197

198

Interface for processing WebSocket messages and managing the WebSocket protocol lifecycle.

199

200

```java { .api }

201

/**

202

* Process WebSocket messages and manage protocol lifecycle

203

*/

204

public interface WebSocketProcessor {

205

/**

206

* Open WebSocket connection

207

* @param webSocket the WebSocket to open

208

* @return WebSocket instance

209

*/

210

public WebSocket open(WebSocket webSocket);

211

212

/**

213

* Invoke WebSocket protocol handling

214

* @param webSocket the WebSocket

215

* @param webSocketMessage message to process

216

*/

217

public void invokeWebSocketProtocol(WebSocket webSocket, String webSocketMessage);

218

219

/**

220

* Close WebSocket connection

221

* @param webSocket the WebSocket to close

222

* @param closeCode close status code

223

*/

224

public void close(WebSocket webSocket, int closeCode);

225

226

/**

227

* Destroy processor and cleanup resources

228

*/

229

public void destroy();

230

}

231

```

232

233

### DefaultWebSocketProcessor

234

235

Default implementation of WebSocketProcessor providing standard WebSocket message processing.

236

237

```java { .api }

238

/**

239

* Default WebSocket message processor

240

*/

241

public class DefaultWebSocketProcessor implements WebSocketProcessor {

242

/**

243

* Create processor with AtmosphereFramework

244

* @param framework AtmosphereFramework instance

245

*/

246

public DefaultWebSocketProcessor(AtmosphereFramework framework);

247

248

/**

249

* Register WebSocketHandler for path pattern

250

* @param path URL path pattern

251

* @param handler WebSocketHandler instance

252

* @return this processor

253

*/

254

public DefaultWebSocketProcessor registerWebSocketHandler(String path, WebSocketHandler handler);

255

}

256

```

257

258

### WebSocketProtocol Interface

259

260

Interface for defining custom WebSocket message protocols and handling protocol-specific logic.

261

262

```java { .api }

263

/**

264

* Define WebSocket message protocols

265

*/

266

public interface WebSocketProtocol {

267

/**

268

* Handle incoming WebSocket message according to protocol

269

* @param webSocket the WebSocket connection

270

* @param message the incoming message

271

* @return list of processed messages for broadcast

272

*/

273

public List<AtmosphereRequest> onMessage(WebSocket webSocket, String message);

274

275

/**

276

* Configure the protocol

277

* @param config AtmosphereConfig for setup

278

*/

279

public void configure(AtmosphereConfig config);

280

281

/**

282

* Get supported protocols

283

* @return list of supported protocol names

284

*/

285

public List<String> supportedProtocols();

286

287

/**

288

* Inspect message and determine if protocol applies

289

* @param message message to inspect

290

* @return true if this protocol handles the message

291

*/

292

public boolean inspectResponse();

293

}

294

```

295

296

### Built-in WebSocket Protocols

297

298

Pre-built protocol implementations for common WebSocket communication patterns.

299

300

```java { .api }

301

/**

302

* Simple HTTP-over-WebSocket protocol

303

*/

304

public class SimpleHttpProtocol implements WebSocketProtocol {

305

/**

306

* Create protocol with delimiter

307

* @param delimiter message delimiter character

308

*/

309

public SimpleHttpProtocol(String delimiter);

310

}

311

312

/**

313

* Streaming HTTP protocol for WebSocket

314

*/

315

public class StreamingHttpProtocol implements WebSocketProtocol {

316

/**

317

* Create streaming protocol with delimiter

318

* @param delimiter message delimiter

319

*/

320

public StreamingHttpProtocol(String delimiter);

321

}

322

```

323

324

**Usage Examples:**

325

326

```java

327

// Register custom WebSocket protocol

328

@WebSocketProtocolService

329

public class JsonWebSocketProtocol implements WebSocketProtocol {

330

331

@Override

332

public List<AtmosphereRequest> onMessage(WebSocket webSocket, String message) {

333

List<AtmosphereRequest> requests = new ArrayList<>();

334

335

try {

336

// Parse JSON message

337

JsonObject json = JsonParser.parseString(message).getAsJsonObject();

338

339

// Create AtmosphereRequest from JSON

340

AtmosphereRequest.Builder builder = new AtmosphereRequest.Builder();

341

builder.pathInfo(json.get("path").getAsString());

342

builder.method(json.get("method").getAsString());

343

344

if (json.has("body")) {

345

builder.body(json.get("body").getAsString());

346

}

347

348

requests.add(builder.build());

349

350

} catch (Exception e) {

351

// Send error response

352

webSocket.write("{\"error\":\"Invalid JSON protocol message\"}");

353

}

354

355

return requests;

356

}

357

358

@Override

359

public void configure(AtmosphereConfig config) {

360

// Protocol configuration

361

}

362

363

@Override

364

public List<String> supportedProtocols() {

365

return Arrays.asList("json-protocol");

366

}

367

}

368

```

369

370

### WebSocket Factory

371

372

Factory interface for creating WebSocket instances with different implementations.

373

374

```java { .api }

375

/**

376

* Factory for creating WebSocket instances

377

*/

378

public interface WebSocketFactory {

379

/**

380

* Create WebSocket instance

381

* @param request AtmosphereRequest

382

* @param response AtmosphereResponse

383

* @return WebSocket instance

384

*/

385

public WebSocket create(AtmosphereRequest request, AtmosphereResponse response);

386

387

/**

388

* Find existing WebSocket by AtmosphereResource

389

* @param resource AtmosphereResource

390

* @return WebSocket instance or null

391

*/

392

public WebSocket find(AtmosphereResource resource);

393

}

394

395

/**

396

* Default WebSocket factory implementation

397

*/

398

public class DefaultWebSocketFactory implements WebSocketFactory {

399

/**

400

* Create factory with AtmosphereConfig

401

* @param config AtmosphereConfig instance

402

*/

403

public DefaultWebSocketFactory(AtmosphereConfig config);

404

}

405

```

406

407

### WebSocket Configuration and Management

408

409

Configuration and management utilities for WebSocket connections and behavior.

410

411

```java { .api }

412

/**

413

* WebSocket event listener for monitoring connections

414

*/

415

public interface WebSocketEventListener {

416

/**

417

* Called when any WebSocket opens

418

* @param event WebSocket event

419

*/

420

public void onWebSocketConnect(WebSocketEvent event);

421

422

/**

423

* Called when any WebSocket closes

424

* @param event WebSocket event

425

*/

426

public void onWebSocketClose(WebSocketEvent event);

427

428

/**

429

* Called on WebSocket error

430

* @param event WebSocket event with error

431

*/

432

public void onWebSocketError(WebSocketEvent event);

433

}

434

435

/**

436

* WebSocket event containing connection and context information

437

*/

438

public class WebSocketEvent {

439

/**

440

* Get the WebSocket connection

441

* @return WebSocket instance

442

*/

443

public WebSocket webSocket();

444

445

/**

446

* Get any associated error

447

* @return Throwable or null

448

*/

449

public Throwable throwable();

450

451

/**

452

* Get event type

453

* @return WebSocketEventType enum

454

*/

455

public WebSocketEventType type();

456

}

457

458

/**

459

* Types of WebSocket events

460

*/

461

public enum WebSocketEventType {

462

CONNECT,

463

MESSAGE,

464

CLOSE,

465

ERROR

466

}

467

```

468

469

### AsyncIOWriter Interface

470

471

Interface for asynchronous, non-blocking I/O operations in WebSocket and HTTP streaming contexts.

472

473

```java { .api }

474

/**

475

* Asynchronous I/O writer for non-blocking writes

476

*/

477

public interface AsyncIOWriter {

478

/**

479

* Write data asynchronously

480

* @param resource AtmosphereResource target

481

* @param data data to write

482

* @return Future for async write operation

483

*/

484

public Future<String> write(AtmosphereResource resource, String data);

485

486

/**

487

* Write byte data asynchronously

488

* @param resource AtmosphereResource target

489

* @param data byte array to write

490

* @return Future for async write operation

491

*/

492

public Future<byte[]> write(AtmosphereResource resource, byte[] data);

493

494

/**

495

* Write generic object asynchronously

496

* @param resource AtmosphereResource target

497

* @param data object to write (will be serialized)

498

* @return Future for async write operation

499

*/

500

public Future<Object> write(AtmosphereResource resource, Object data);

501

502

/**

503

* Close the writer and cleanup resources

504

* @param resource AtmosphereResource

505

*/

506

public void close(AtmosphereResource resource);

507

508

/**

509

* Flush pending writes

510

* @param resource AtmosphereResource

511

*/

512

public void flush(AtmosphereResource resource);

513

}

514

515

/**

516

* Default AsyncIOWriter implementation

517

*/

518

public class DefaultAsyncIOWriter implements AsyncIOWriter {

519

/**

520

* Create writer with AtmosphereResponse

521

* @param response AtmosphereResponse for writing

522

*/

523

public DefaultAsyncIOWriter(AtmosphereResponse response);

524

525

/**

526

* Set write timeout

527

* @param timeout write timeout in milliseconds

528

* @return this writer

529

*/

530

public DefaultAsyncIOWriter setTimeout(long timeout);

531

}

532

```

533

534

**Usage Examples:**

535

536

```java

537

@WebSocketHandlerService(path = "/async-websocket")

538

public class AsyncWebSocketHandler implements WebSocketHandler {

539

540

@Override

541

public void onOpen(WebSocket webSocket) {

542

AtmosphereResource resource = webSocket.resource();

543

AsyncIOWriter writer = resource.getResponse().getAsyncIOWriter();

544

545

// Asynchronous welcome message

546

Future<String> writeResult = writer.write(resource, "Welcome! Connection established.");

547

548

writeResult.thenAccept(result -> {

549

System.out.println("Welcome message sent successfully");

550

}).exceptionally(throwable -> {

551

System.err.println("Failed to send welcome message: " + throwable.getMessage());

552

return null;

553

});

554

}

555

556

@Override

557

public void onTextMessage(WebSocket webSocket, String message) {

558

AtmosphereResource resource = webSocket.resource();

559

AsyncIOWriter writer = resource.getResponse().getAsyncIOWriter();

560

561

// Process message asynchronously

562

CompletableFuture.supplyAsync(() -> processMessage(message))

563

.thenCompose(processed -> writer.write(resource, processed))

564

.thenAccept(result -> System.out.println("Response sent"))

565

.exceptionally(throwable -> {

566

System.err.println("Error processing message: " + throwable.getMessage());

567

return null;

568

});

569

}

570

571

private String processMessage(String message) {

572

// Simulate processing

573

try {

574

Thread.sleep(100); // Simulate work

575

} catch (InterruptedException e) {

576

Thread.currentThread().interrupt();

577

}

578

return "Processed: " + message;

579

}

580

}

581

```

582

583

### Complete WebSocket Example

584

585

```java

586

@WebSocketHandlerService(path = "/websocket/chat/{room}")

587

public class ChatWebSocketHandler implements WebSocketHandler {

588

private final Map<String, Set<WebSocket>> roomConnections = new ConcurrentHashMap<>();

589

590

@Override

591

public void onOpen(WebSocket webSocket) {

592

// Extract room from path

593

String room = extractRoomFromPath(webSocket.resource().getRequest().getPathInfo());

594

595

// Add to room connections

596

roomConnections.computeIfAbsent(room, k -> ConcurrentHashMap.newKeySet())

597

.add(webSocket);

598

599

// Send welcome message

600

webSocket.write(createMessage("system", "Welcome to room " + room));

601

602

// Notify room of new user

603

broadcastToRoom(room, createMessage("system", "User joined the room"), webSocket);

604

605

System.out.println("WebSocket opened for room: " + room);

606

}

607

608

@Override

609

public void onTextMessage(WebSocket webSocket, String message) {

610

String room = extractRoomFromPath(webSocket.resource().getRequest().getPathInfo());

611

612

try {

613

// Parse incoming message

614

JsonObject json = JsonParser.parseString(message).getAsJsonObject();

615

String type = json.get("type").getAsString();

616

617

switch (type) {

618

case "chat":

619

String text = json.get("text").getAsString();

620

String user = json.get("user").getAsString();

621

622

// Broadcast chat message to room

623

String chatMessage = createMessage("chat", text, user);

624

broadcastToRoom(room, chatMessage, null); // Include sender

625

break;

626

627

case "typing":

628

String typingUser = json.get("user").getAsString();

629

String typingMessage = createMessage("typing", typingUser + " is typing...");

630

broadcastToRoom(room, typingMessage, webSocket); // Exclude sender

631

break;

632

633

default:

634

webSocket.write(createMessage("error", "Unknown message type"));

635

}

636

} catch (Exception e) {

637

webSocket.write(createMessage("error", "Invalid message format"));

638

}

639

}

640

641

@Override

642

public void onClose(WebSocket webSocket) {

643

String room = extractRoomFromPath(webSocket.resource().getRequest().getPathInfo());

644

645

// Remove from room connections

646

Set<WebSocket> connections = roomConnections.get(room);

647

if (connections != null) {

648

connections.remove(webSocket);

649

if (connections.isEmpty()) {

650

roomConnections.remove(room);

651

}

652

}

653

654

// Notify room of user leaving

655

broadcastToRoom(room, createMessage("system", "User left the room"), null);

656

657

System.out.println("WebSocket closed for room: " + room);

658

}

659

660

@Override

661

public void onError(WebSocket webSocket, Throwable t) {

662

System.err.println("WebSocket error: " + t.getMessage());

663

t.printStackTrace();

664

665

// Send error message to client

666

webSocket.write(createMessage("error", "Connection error occurred"));

667

}

668

669

private void broadcastToRoom(String room, String message, WebSocket exclude) {

670

Set<WebSocket> connections = roomConnections.get(room);

671

if (connections != null) {

672

connections.stream()

673

.filter(ws -> ws != exclude && ws.isOpen())

674

.forEach(ws -> ws.write(message));

675

}

676

}

677

678

private String createMessage(String type, String content) {

679

return String.format("{\"type\":\"%s\",\"content\":\"%s\",\"timestamp\":%d}",

680

type, content, System.currentTimeMillis());

681

}

682

683

private String createMessage(String type, String content, String user) {

684

return String.format("{\"type\":\"%s\",\"content\":\"%s\",\"user\":\"%s\",\"timestamp\":%d}",

685

type, content, user, System.currentTimeMillis());

686

}

687

688

private String extractRoomFromPath(String pathInfo) {

689

// Extract room from path like "/websocket/chat/room123"

690

String[] parts = pathInfo.split("/");

691

return parts.length > 3 ? parts[3] : "default";

692

}

693

}

694

```