0
# Connection Management
1
2
Jetty IO provides comprehensive connection management capabilities including client connection factories, transport abstractions, and connection lifecycle management for establishing and managing network connections.
3
4
## Capabilities
5
6
### ClientConnectionFactory Interface
7
8
Factory interface for creating client-side connections with protocol-specific implementations.
9
10
```java { .api }
11
/**
12
* Factory for client-side Connection instances
13
*/
14
interface ClientConnectionFactory {
15
/**
16
* Create a new connection for the given endpoint and context
17
* @param endPoint the endpoint for the connection
18
* @param context connection context containing configuration and state
19
* @return new Connection instance
20
* @throws IOException if connection creation fails
21
*/
22
Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException;
23
24
/**
25
* Customize a connection after creation
26
* @param connection the connection to customize
27
* @param context connection context
28
* @return the customized connection (may be the same instance or a wrapper)
29
*/
30
default Connection customize(Connection connection, Map<String, Object> context) {
31
return connection;
32
}
33
34
// Context key for client information
35
String CLIENT_CONTEXT_KEY = "client";
36
37
interface Decorator {
38
/** Decorate (wrap) a connection factory */
39
ClientConnectionFactory decorate(ClientConnectionFactory factory);
40
}
41
42
abstract class Info {
43
private final String protocol;
44
private final ClientConnectionFactory factory;
45
46
protected Info(String protocol, ClientConnectionFactory factory);
47
48
public String getProtocol();
49
public ClientConnectionFactory getClientConnectionFactory();
50
public boolean matches(String protocol, String protocols);
51
}
52
}
53
```
54
55
**Usage Examples:**
56
57
```java
58
// HTTP/1.1 client connection factory
59
ClientConnectionFactory http11Factory = new ClientConnectionFactory() {
60
@Override
61
public Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException {
62
HttpClient client = (HttpClient) context.get(CLIENT_CONTEXT_KEY);
63
return new HttpConnection(endPoint, client);
64
}
65
};
66
67
// WebSocket client connection factory
68
ClientConnectionFactory wsFactory = new ClientConnectionFactory() {
69
@Override
70
public Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException {
71
WebSocketClient client = (WebSocketClient) context.get(CLIENT_CONTEXT_KEY);
72
return new WebSocketConnection(endPoint, client);
73
}
74
};
75
76
// Decorating factory for logging
77
ClientConnectionFactory.Decorator loggingDecorator = factory -> new ClientConnectionFactory() {
78
@Override
79
public Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException {
80
System.out.println("Creating connection to: " + endPoint.getRemoteSocketAddress());
81
Connection connection = factory.newConnection(endPoint, context);
82
return new LoggingConnection(connection);
83
}
84
};
85
86
ClientConnectionFactory decoratedFactory = loggingDecorator.decorate(http11Factory);
87
88
// Using connection context
89
Map<String, Object> context = new HashMap<>();
90
context.put(ClientConnectionFactory.CLIENT_CONTEXT_KEY, httpClient);
91
context.put("request.timeout", Duration.ofSeconds(30));
92
93
EndPoint endPoint = // ... create endpoint
94
Connection connection = http11Factory.newConnection(endPoint, context);
95
```
96
97
### Transport Interface
98
99
Low-level transport abstraction supporting different networking protocols (TCP, UDP, Unix domain sockets).
100
101
```java { .api }
102
/**
103
* Low-level transport abstraction (TCP, UDP, Unix sockets, etc.)
104
*/
105
interface Transport {
106
/** Check if transport provides intrinsic security (e.g., Unix domain sockets) */
107
boolean isIntrinsicallySecure();
108
109
/** Check if transport requires domain name resolution */
110
boolean requiresDomainNameResolution();
111
112
/**
113
* Connect to remote address
114
* @param socketAddress target address to connect to
115
* @param context connection context
116
* @throws IOException if connection fails
117
*/
118
void connect(SocketAddress socketAddress, Map<String, Object> context) throws IOException;
119
120
/** Get the socket address for this transport */
121
SocketAddress getSocketAddress();
122
123
/** Create a new selectable channel for this transport */
124
SelectableChannel newSelectableChannel() throws IOException;
125
126
/**
127
* Create new endpoint for this transport
128
* @param scheduler scheduler for endpoint operations
129
* @param selector managed selector for NIO operations
130
* @param channel the selectable channel
131
* @param key the selection key
132
* @return new EndPoint instance
133
*/
134
EndPoint newEndPoint(Scheduler scheduler, ManagedSelector selector,
135
SelectableChannel channel, SelectionKey key);
136
137
/**
138
* Create new connection for this transport
139
* @param endPoint the endpoint
140
* @param context connection context
141
* @return new Connection instance
142
* @throws IOException if connection creation fails
143
*/
144
Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException;
145
146
// Built-in transport instances
147
Transport TCP_IP = new TCPIP();
148
Transport UDP_IP = new UDPIP();
149
150
abstract class Socket implements Transport {
151
public abstract SocketAddress getSocketAddress();
152
public boolean isIntrinsicallySecure();
153
public boolean requiresDomainNameResolution();
154
}
155
156
abstract class IP extends Socket {
157
protected final String host;
158
protected final int port;
159
160
protected IP(String host, int port);
161
162
public String getHost();
163
public int getPort();
164
public SocketAddress getSocketAddress();
165
public boolean requiresDomainNameResolution();
166
}
167
168
class TCPIP extends IP {
169
public TCPIP(String host, int port);
170
public SelectableChannel newSelectableChannel() throws IOException;
171
public EndPoint newEndPoint(Scheduler scheduler, ManagedSelector selector,
172
SelectableChannel channel, SelectionKey key);
173
public void connect(SocketAddress address, Map<String, Object> context) throws IOException;
174
}
175
176
class UDPIP extends IP {
177
public UDPIP(String host, int port);
178
public SelectableChannel newSelectableChannel() throws IOException;
179
public EndPoint newEndPoint(Scheduler scheduler, ManagedSelector selector,
180
SelectableChannel channel, SelectionKey key);
181
public void connect(SocketAddress address, Map<String, Object> context) throws IOException;
182
}
183
184
abstract class Unix extends Socket {
185
protected final Path path;
186
187
protected Unix(Path path);
188
189
public Path getPath();
190
public SocketAddress getSocketAddress();
191
public boolean isIntrinsicallySecure();
192
public boolean requiresDomainNameResolution();
193
}
194
195
class TCPUnix extends Unix {
196
public TCPUnix(Path path);
197
public SelectableChannel newSelectableChannel() throws IOException;
198
public EndPoint newEndPoint(Scheduler scheduler, ManagedSelector selector,
199
SelectableChannel channel, SelectionKey key);
200
}
201
202
class UDPUnix extends Unix {
203
public UDPUnix(Path path);
204
public SelectableChannel newSelectableChannel() throws IOException;
205
public EndPoint newEndPoint(Scheduler scheduler, ManagedSelector selector,
206
SelectableChannel channel, SelectionKey key);
207
}
208
209
class Wrapper implements Transport {
210
private final Transport wrapped;
211
212
public Wrapper(Transport wrapped);
213
public Transport getWrapped();
214
215
// All methods delegate to wrapped transport
216
public boolean isIntrinsicallySecure();
217
public boolean requiresDomainNameResolution();
218
// ... other delegating methods
219
}
220
}
221
```
222
223
**Usage Examples:**
224
225
```java
226
// TCP/IP transport
227
Transport tcpTransport = new Transport.TCPIP("example.com", 8080);
228
System.out.println("Requires DNS resolution: " + tcpTransport.requiresDomainNameResolution());
229
System.out.println("Socket address: " + tcpTransport.getSocketAddress());
230
231
// UDP/IP transport
232
Transport udpTransport = new Transport.UDPIP("224.0.0.1", 5000); // Multicast
233
SelectableChannel udpChannel = udpTransport.newSelectableChannel();
234
235
// Unix domain socket transport
236
Path socketPath = Paths.get("/tmp/app.sock");
237
Transport unixTransport = new Transport.TCPUnix(socketPath);
238
System.out.println("Intrinsically secure: " + unixTransport.isIntrinsicallySecure());
239
240
// Transport wrapper for custom behavior
241
Transport loggingTransport = new Transport.Wrapper(tcpTransport) {
242
@Override
243
public void connect(SocketAddress address, Map<String, Object> context) throws IOException {
244
System.out.println("Connecting to: " + address);
245
super.connect(address, context);
246
System.out.println("Connected successfully");
247
}
248
};
249
250
// Creating endpoint with transport
251
Scheduler scheduler = // ... scheduler instance
252
ManagedSelector selector = // ... managed selector instance
253
SelectableChannel channel = tcpTransport.newSelectableChannel();
254
SelectionKey key = channel.register(selector.getSelector(), SelectionKey.OP_CONNECT);
255
EndPoint endPoint = tcpTransport.newEndPoint(scheduler, selector, channel, key);
256
257
// Creating connection with transport
258
Map<String, Object> context = new HashMap<>();
259
Connection connection = tcpTransport.newConnection(endPoint, context);
260
```
261
262
### ClientConnector
263
264
High-level client connector that manages the connection establishment process.
265
266
```java { .api }
267
/**
268
* Client-side connector for establishing connections
269
*/
270
class ClientConnector extends ContainerLifeCycle {
271
public ClientConnector();
272
273
// Configuration
274
public void setSelectors(int selectors);
275
public int getSelectors();
276
277
public void setIdleTimeout(Duration idleTimeout);
278
public Duration getIdleTimeout();
279
280
public void setConnectTimeout(Duration connectTimeout);
281
public Duration getConnectTimeout();
282
283
public void setByteBufferPool(ByteBufferPool pool);
284
public ByteBufferPool getByteBufferPool();
285
286
public void setScheduler(Scheduler scheduler);
287
public Scheduler getScheduler();
288
289
public void setExecutor(Executor executor);
290
public Executor getExecutor();
291
292
public void setSslContextFactory(SslContextFactory.Client sslContextFactory);
293
public SslContextFactory.Client getSslContextFactory();
294
295
// Connection establishment
296
public CompletableFuture<Connection> connect(SocketAddress address, Map<String, Object> context);
297
public CompletableFuture<Connection> connect(Transport transport, Map<String, Object> context);
298
299
// Statistics
300
public ConnectionStatistics getConnectionStatistics();
301
}
302
```
303
304
**Usage Examples:**
305
306
```java
307
// Basic client connector setup
308
ClientConnector connector = new ClientConnector();
309
connector.setSelectors(4); // 4 selector threads
310
connector.setIdleTimeout(Duration.ofSeconds(30));
311
connector.setConnectTimeout(Duration.ofSeconds(15));
312
313
// Custom buffer pool
314
ByteBufferPool customPool = new ArrayByteBufferPool(256, 2, 65536, 64);
315
connector.setByteBufferPool(customPool);
316
317
// Custom scheduler and executor
318
connector.setScheduler(new ScheduledExecutorScheduler("client-scheduler", false));
319
connector.setExecutor(new QueuedThreadPool("client-executor"));
320
321
// SSL configuration
322
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
323
sslContextFactory.setTrustAll(false);
324
sslContextFactory.setEndpointIdentificationAlgorithm("HTTPS");
325
connector.setSslContextFactory(sslContextFactory);
326
327
// Start connector
328
connector.start();
329
330
// Connect to server
331
SocketAddress address = new InetSocketAddress("example.com", 443);
332
Map<String, Object> context = new HashMap<>();
333
context.put(ClientConnectionFactory.CLIENT_CONTEXT_KEY, httpClient);
334
335
CompletableFuture<Connection> connectionFuture = connector.connect(address, context);
336
connectionFuture.thenAccept(connection -> {
337
System.out.println("Connected to: " + connection.getEndPoint().getRemoteSocketAddress());
338
// Use connection
339
}).exceptionally(throwable -> {
340
System.err.println("Connection failed: " + throwable.getMessage());
341
return null;
342
});
343
344
// Connect with custom transport
345
Transport customTransport = new Transport.TCPIP("example.com", 8080);
346
CompletableFuture<Connection> customConnection = connector.connect(customTransport, context);
347
348
// Monitor connection statistics
349
ConnectionStatistics stats = connector.getConnectionStatistics();
350
System.out.println("Total connections: " + stats.getConnectionsTotal());
351
System.out.println("Open connections: " + stats.getConnectionsOpened());
352
```
353
354
### NegotiatingClientConnection
355
356
Client connection that supports protocol negotiation during connection establishment.
357
358
```java { .api }
359
/**
360
* Client connection that can negotiate protocols
361
*/
362
class NegotiatingClientConnection extends AbstractConnection {
363
protected NegotiatingClientConnection(EndPoint endPoint, Executor executor,
364
ClientConnectionFactory connectionFactory,
365
Map<String, Object> context);
366
367
// Protocol negotiation
368
protected void negotiate();
369
protected String selectProtocol(List<String> protocols);
370
protected Connection newConnection(String protocol);
371
372
// Lifecycle
373
public void onOpen();
374
public void onFillable();
375
public boolean onIdleExpired(TimeoutException timeoutException);
376
}
377
```
378
379
### NegotiatingClientConnectionFactory
380
381
Factory for creating negotiating client connections.
382
383
```java { .api }
384
/**
385
* Factory for negotiating client connections
386
*/
387
class NegotiatingClientConnectionFactory implements ClientConnectionFactory {
388
public NegotiatingClientConnectionFactory(ClientConnectionFactory connectionFactory,
389
String... protocols);
390
391
public Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException;
392
393
public List<String> getProtocols();
394
public ClientConnectionFactory getClientConnectionFactory();
395
}
396
```
397
398
**Negotiation Examples:**
399
400
```java
401
// HTTP/2 with HTTP/1.1 fallback
402
ClientConnectionFactory http2Factory = new HTTP2ClientConnectionFactory();
403
ClientConnectionFactory http11Factory = new HTTP11ClientConnectionFactory();
404
405
NegotiatingClientConnectionFactory negotiatingFactory =
406
new NegotiatingClientConnectionFactory(http2Factory, "h2", "http/1.1");
407
408
// ALPN negotiation will occur during SSL handshake
409
Map<String, Object> context = new HashMap<>();
410
context.put(ClientConnectionFactory.CLIENT_CONTEXT_KEY, httpClient);
411
412
Connection connection = negotiatingFactory.newConnection(sslEndPoint, context);
413
// Connection will negotiate to HTTP/2 if supported, fallback to HTTP/1.1
414
415
// Custom negotiation logic
416
NegotiatingClientConnection customNegotiation = new NegotiatingClientConnection(
417
endPoint, executor, connectionFactory, context) {
418
419
@Override
420
protected String selectProtocol(List<String> protocols) {
421
// Custom protocol selection logic
422
if (protocols.contains("custom-protocol-v2")) {
423
return "custom-protocol-v2";
424
} else if (protocols.contains("custom-protocol-v1")) {
425
return "custom-protocol-v1";
426
}
427
return super.selectProtocol(protocols);
428
}
429
430
@Override
431
protected Connection newConnection(String protocol) {
432
switch (protocol) {
433
case "custom-protocol-v2":
434
return new CustomV2Connection(getEndPoint(), getExecutor());
435
case "custom-protocol-v1":
436
return new CustomV1Connection(getEndPoint(), getExecutor());
437
default:
438
return super.newConnection(protocol);
439
}
440
}
441
};
442
```
443
444
### Connection Statistics and Monitoring
445
446
```java { .api }
447
/**
448
* Statistics collection for connections
449
*/
450
class ConnectionStatistics extends AbstractLifeCycle implements Connection.Listener {
451
public ConnectionStatistics();
452
453
// Connection counts
454
public long getConnectionsTotal();
455
public long getConnectionsOpened();
456
public long getConnectionsClosed();
457
public long getConnectionsMax();
458
459
// Message counts
460
public long getMessagesIn();
461
public long getMessagesOut();
462
463
// Byte counts
464
public long getBytesIn();
465
public long getBytesOut();
466
467
// Timing statistics
468
public long getConnectionDurationMax();
469
public double getConnectionDurationMean();
470
public double getConnectionDurationStdDev();
471
472
// Rate statistics
473
public double getConnectionsPerSecond();
474
public double getMessagesInPerSecond();
475
public double getMessagesOutPerSecond();
476
477
// Reset statistics
478
public void reset();
479
480
// Connection listener methods
481
public void onOpened(Connection connection);
482
public void onClosed(Connection connection);
483
}
484
```
485
486
**Statistics Usage:**
487
488
```java
489
// Monitor connection statistics
490
ConnectionStatistics stats = new ConnectionStatistics();
491
492
// Add as listener to connections
493
connection.addEventListener(stats);
494
495
// Or add to connector for all connections
496
ClientConnector connector = new ClientConnector();
497
connector.addBean(stats);
498
499
// Monitor statistics
500
Timer timer = new Timer();
501
timer.scheduleAtFixedRate(new TimerTask() {
502
@Override
503
public void run() {
504
System.out.printf("Connections: total=%d, open=%d, closed=%d%n",
505
stats.getConnectionsTotal(),
506
stats.getConnectionsOpened(),
507
stats.getConnectionsClosed());
508
System.out.printf("Throughput: %.2f conn/sec, %.2f KB/sec in, %.2f KB/sec out%n",
509
stats.getConnectionsPerSecond(),
510
stats.getBytesIn() / 1024.0,
511
stats.getBytesOut() / 1024.0);
512
}
513
}, 0, 5000); // Every 5 seconds
514
515
// Include/exclude based connection statistics
516
IncludeExcludeConnectionStatistics filteredStats = new IncludeExcludeConnectionStatistics();
517
filteredStats.include("https://api.example.com:*");
518
filteredStats.exclude("https://internal.example.com:*");
519
520
// Only connections matching include patterns and not matching exclude patterns
521
// will be counted in statistics
522
```