or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-support.mdconfiguration.mdcore-websocket-api.mdhandler-framework.mdindex.mdmessage-types.mdserver-integration.mdsockjs-support.mdstomp-messaging.md

client-support.mddocs/

0

# Client Support

1

2

WebSocket client implementations for establishing outbound WebSocket connections with connection management.

3

4

## Capabilities

5

6

### WebSocket Client Interface

7

8

Contract for initiating WebSocket requests to connect to a WebSocket server.

9

10

```java { .api }

11

/**

12

* Contract for initiating WebSocket requests to connect to a WebSocket server.

13

* Implementations handle the WebSocket handshake and connection establishment.

14

*/

15

interface WebSocketClient {

16

/**

17

* Execute WebSocket handshake using URI template.

18

* @param webSocketHandler handler for the connection

19

* @param uriTemplate URI template for the WebSocket endpoint

20

* @param uriVariables variables to substitute in the URI template

21

* @return future that completes when connection is established

22

*/

23

CompletableFuture<WebSocketSession> execute(

24

WebSocketHandler webSocketHandler,

25

String uriTemplate,

26

Object... uriVariables

27

);

28

29

/**

30

* Execute WebSocket handshake with headers and URI.

31

* @param webSocketHandler handler for the connection

32

* @param headers HTTP headers for the handshake request

33

* @param uri URI of the WebSocket endpoint

34

* @return future that completes when connection is established

35

*/

36

CompletableFuture<WebSocketSession> execute(

37

WebSocketHandler webSocketHandler,

38

@Nullable WebSocketHttpHeaders headers,

39

URI uri

40

);

41

42

/**

43

* Execute WebSocket handshake using URI template.

44

* @deprecated as of 5.0, in favor of {@link #execute}

45

*/

46

@Deprecated

47

CompletableFuture<WebSocketSession> doHandshake(

48

WebSocketHandler webSocketHandler,

49

String uriTemplate,

50

Object... uriVariables

51

);

52

53

/**

54

* Execute WebSocket handshake with headers and URI.

55

* @deprecated as of 5.0, in favor of {@link #execute}

56

*/

57

@Deprecated

58

CompletableFuture<WebSocketSession> doHandshake(

59

WebSocketHandler webSocketHandler,

60

@Nullable WebSocketHttpHeaders headers,

61

URI uri

62

);

63

}

64

```

65

66

**Usage Example:**

67

68

```java

69

@Service

70

public class WebSocketClientService {

71

private final WebSocketClient client;

72

private final WebSocketHandler handler;

73

74

public WebSocketClientService() {

75

this.client = new StandardWebSocketClient();

76

this.handler = new ClientWebSocketHandler();

77

}

78

79

public CompletableFuture<WebSocketSession> connectToServer(String serverUrl) {

80

// Simple connection

81

ListenableFuture<WebSocketSession> future = client.doHandshake(

82

handler,

83

serverUrl

84

);

85

86

return toCompletableFuture(future);

87

}

88

89

public CompletableFuture<WebSocketSession> connectWithAuth(String serverUrl, String token) {

90

// Connection with authentication headers

91

WebSocketHttpHeaders headers = new WebSocketHttpHeaders();

92

headers.add("Authorization", "Bearer " + token);

93

headers.setSecWebSocketProtocol("chat", "echo");

94

95

URI uri = URI.create(serverUrl);

96

ListenableFuture<WebSocketSession> future = client.doHandshake(

97

handler,

98

headers,

99

uri

100

);

101

102

return toCompletableFuture(future);

103

}

104

105

public CompletableFuture<WebSocketSession> connectWithTemplate(String userId) {

106

// Connection using URI template

107

ListenableFuture<WebSocketSession> future = client.doHandshake(

108

handler,

109

"ws://localhost:8080/user/{userId}/websocket",

110

userId

111

);

112

113

return toCompletableFuture(future);

114

}

115

116

private CompletableFuture<WebSocketSession> toCompletableFuture(ListenableFuture<WebSocketSession> future) {

117

CompletableFuture<WebSocketSession> completableFuture = new CompletableFuture<>();

118

119

future.addCallback(

120

completableFuture::complete,

121

completableFuture::completeExceptionally

122

);

123

124

return completableFuture;

125

}

126

}

127

```

128

129

### Connection Management

130

131

Base classes for managing WebSocket connections with lifecycle support.

132

133

```java { .api }

134

/**

135

* Base class for connection managers that establish connections on startup.

136

* Implements Spring lifecycle interfaces for automatic connection management.

137

*/

138

abstract class ConnectionManagerSupport implements SmartLifecycle {

139

/**

140

* Set whether the connection should start automatically.

141

* @param autoStartup true to start automatically

142

*/

143

public void setAutoStartup(boolean autoStartup);

144

145

/**

146

* Check if auto-startup is enabled.

147

* @return true if auto-startup is enabled

148

*/

149

public boolean isAutoStartup();

150

151

/**

152

* Set the lifecycle phase for startup ordering.

153

* @param phase the lifecycle phase

154

*/

155

public void setPhase(int phase);

156

157

/**

158

* Get the lifecycle phase.

159

* @return the lifecycle phase

160

*/

161

public int getPhase();

162

163

/**

164

* Start the connection manager.

165

*/

166

public void start();

167

168

/**

169

* Stop the connection manager.

170

*/

171

public void stop();

172

173

/**

174

* Check if the connection manager is running.

175

* @return true if running

176

*/

177

public boolean isRunning();

178

}

179

180

/**

181

* Connection manager for establishing and maintaining WebSocket connections.

182

* Automatically reconnects on connection failure.

183

*/

184

class WebSocketConnectionManager extends ConnectionManagerSupport {

185

/**

186

* Create connection manager with URI template.

187

* @param client WebSocket client implementation

188

* @param webSocketHandler handler for the connection

189

* @param uriTemplate URI template for the endpoint

190

* @param uriVariables variables for the URI template

191

*/

192

public WebSocketConnectionManager(

193

WebSocketClient client,

194

WebSocketHandler webSocketHandler,

195

String uriTemplate,

196

Object... uriVariables

197

);

198

199

/**

200

* Set the connection URI.

201

* @param uri WebSocket endpoint URI

202

*/

203

public void setUri(URI uri);

204

205

/**

206

* Get the connection URI.

207

* @return WebSocket endpoint URI

208

*/

209

public URI getUri();

210

211

/**

212

* Set handshake headers.

213

* @param headers HTTP headers for handshake

214

*/

215

public void setHeaders(HttpHeaders headers);

216

217

/**

218

* Get handshake headers.

219

* @return HTTP headers for handshake

220

*/

221

public HttpHeaders getHeaders();

222

}

223

```

224

225

**Usage Example:**

226

227

```java

228

@Configuration

229

@EnableScheduling

230

public class WebSocketClientConfig {

231

232

@Bean

233

public WebSocketClient webSocketClient() {

234

return new StandardWebSocketClient();

235

}

236

237

@Bean

238

public WebSocketConnectionManager chatConnectionManager(

239

WebSocketClient client,

240

ChatClientHandler handler) {

241

242

WebSocketConnectionManager manager = new WebSocketConnectionManager(

243

client,

244

handler,

245

"ws://chat-server.example.com/chat"

246

);

247

248

// Configure connection manager

249

manager.setAutoStartup(true);

250

manager.setPhase(1000); // Start after other beans

251

252

// Add authentication headers

253

HttpHeaders headers = new HttpHeaders();

254

headers.add("Authorization", "Bearer ${chat.auth.token}");

255

manager.setHeaders(headers);

256

257

return manager;

258

}

259

260

@Bean

261

public WebSocketConnectionManager notificationConnectionManager(

262

WebSocketClient client,

263

NotificationClientHandler handler) {

264

265

WebSocketConnectionManager manager = new WebSocketConnectionManager(

266

client,

267

handler,

268

"wss://notifications.example.com/user/{userId}/notifications",

269

"${user.id}"

270

);

271

272

manager.setAutoStartup(true);

273

return manager;

274

}

275

}

276

277

@Component

278

public class ChatClientHandler extends AbstractWebSocketHandler {

279

280

@Override

281

public void afterConnectionEstablished(WebSocketSession session) throws Exception {

282

logger.info("Connected to chat server: {}", session.getUri());

283

session.sendMessage(new TextMessage("Hello from client!"));

284

}

285

286

@Override

287

protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {

288

logger.info("Received message: {}", message.getPayload());

289

// Process incoming chat message

290

processChatMessage(message.getPayload());

291

}

292

293

@Override

294

public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {

295

logger.error("Transport error: {}", exception.getMessage());

296

// Connection manager will automatically attempt reconnection

297

}

298

299

@Override

300

public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {

301

logger.info("Connection closed: {} - {}", closeStatus.getCode(), closeStatus.getReason());

302

}

303

}

304

```

305

306

### Standard WebSocket Client

307

308

JSR-356 based WebSocket client implementation.

309

310

```java { .api }

311

/**

312

* WebSocket client implementation based on JSR-356 standard.

313

* Uses the standard WebSocketContainer for connections.

314

*/

315

class StandardWebSocketClient extends AbstractWebSocketClient implements WebSocketClient {

316

/**

317

* Create client with default WebSocketContainer.

318

*/

319

public StandardWebSocketClient();

320

321

/**

322

* Create client with custom WebSocketContainer.

323

* @param webSocketContainer JSR-356 WebSocket container

324

*/

325

public StandardWebSocketClient(WebSocketContainer webSocketContainer);

326

327

/**

328

* Set user properties for WebSocket connections.

329

* @param userProperties properties to set on WebSocket sessions

330

*/

331

public void setUserProperties(Map<String, Object> userProperties);

332

333

/**

334

* Get user properties.

335

* @return user properties map

336

*/

337

public Map<String, Object> getUserProperties();

338

}

339

```

340

341

**Usage Example:**

342

343

```java

344

@Configuration

345

public class StandardWebSocketClientConfig {

346

347

@Bean

348

public WebSocketContainer webSocketContainer() {

349

WebSocketContainer container = ContainerProvider.getWebSocketContainer();

350

351

// Configure container properties

352

container.setDefaultMaxSessionIdleTimeout(300000); // 5 minutes

353

container.setDefaultMaxTextMessageBufferSize(64 * 1024); // 64KB

354

container.setDefaultMaxBinaryMessageBufferSize(64 * 1024); // 64KB

355

356

return container;

357

}

358

359

@Bean

360

public StandardWebSocketClient standardWebSocketClient(WebSocketContainer container) {

361

StandardWebSocketClient client = new StandardWebSocketClient(container);

362

363

// Set user properties for all connections

364

Map<String, Object> userProperties = new HashMap<>();

365

userProperties.put("client.version", "1.0");

366

userProperties.put("client.type", "spring-boot");

367

client.setUserProperties(userProperties);

368

369

return client;

370

}

371

}

372

373

@Service

374

public class FileTransferClient {

375

private final StandardWebSocketClient client;

376

377

public FileTransferClient(StandardWebSocketClient client) {

378

this.client = client;

379

}

380

381

public CompletableFuture<Void> uploadFile(String serverUrl, Path filePath) {

382

WebSocketHandler handler = new FileUploadHandler(filePath);

383

384

return client.doHandshake(handler, serverUrl)

385

.toCompletableFuture()

386

.thenCompose(session -> uploadFileContent(session, filePath));

387

}

388

389

private CompletableFuture<Void> uploadFileContent(WebSocketSession session, Path filePath) {

390

return CompletableFuture.runAsync(() -> {

391

try (FileInputStream fis = new FileInputStream(filePath.toFile())) {

392

byte[] buffer = new byte[8192];

393

int bytesRead;

394

395

while ((bytesRead = fis.read(buffer)) != -1) {

396

boolean isLast = (fis.available() == 0);

397

BinaryMessage chunk = new BinaryMessage(buffer, 0, bytesRead, isLast);

398

session.sendMessage(chunk);

399

}

400

401

session.close(CloseStatus.NORMAL);

402

} catch (IOException e) {

403

throw new RuntimeException("File upload failed", e);

404

}

405

});

406

}

407

}

408

```

409

410

### WebSocket Container Configuration

411

412

Factory bean for configuring JSR-356 WebSocket containers.

413

414

```java { .api }

415

/**

416

* Factory bean for creating and configuring JSR-356 WebSocketContainer.

417

* Provides Spring integration for WebSocket container configuration.

418

*/

419

class WebSocketContainerFactoryBean implements FactoryBean<WebSocketContainer>, InitializingBean {

420

/**

421

* Set the maximum session idle timeout.

422

* @param maxSessionIdleTimeout timeout in milliseconds

423

*/

424

public void setMaxSessionIdleTimeout(long maxSessionIdleTimeout);

425

426

/**

427

* Set the maximum text message buffer size.

428

* @param maxTextMessageBufferSize buffer size in bytes

429

*/

430

public void setMaxTextMessageBufferSize(int maxTextMessageBufferSize);

431

432

/**

433

* Set the maximum binary message buffer size.

434

* @param maxBinaryMessageBufferSize buffer size in bytes

435

*/

436

public void setMaxBinaryMessageBufferSize(int maxBinaryMessageBufferSize);

437

438

/**

439

* Set the async send timeout.

440

* @param asyncSendTimeout timeout in milliseconds

441

*/

442

public void setAsyncSendTimeout(long asyncSendTimeout);

443

444

/**

445

* Get the configured WebSocketContainer.

446

* @return configured WebSocket container

447

*/

448

public WebSocketContainer getObject();

449

450

/**

451

* Get the WebSocket container type.

452

* @return WebSocketContainer class

453

*/

454

public Class<?> getObjectType();

455

456

/**

457

* Check if the container is a singleton.

458

* @return true (container is singleton)

459

*/

460

public boolean isSingleton();

461

}

462

```

463

464

**Usage Example:**

465

466

```java

467

@Configuration

468

public class WebSocketContainerConfig {

469

470

@Bean

471

public WebSocketContainerFactoryBean webSocketContainer() {

472

WebSocketContainerFactoryBean factory = new WebSocketContainerFactoryBean();

473

474

factory.setMaxSessionIdleTimeout(300000); // 5 minutes

475

factory.setMaxTextMessageBufferSize(128 * 1024); // 128KB

476

factory.setMaxBinaryMessageBufferSize(512 * 1024); // 512KB

477

factory.setAsyncSendTimeout(10000); // 10 seconds

478

479

return factory;

480

}

481

482

@Bean

483

public StandardWebSocketClient webSocketClient(WebSocketContainer container) {

484

return new StandardWebSocketClient(container);

485

}

486

}

487

```