18
18
19
19
import java .net .URI ;
20
20
21
- import org .eclipse .jetty .websocket .api .Session ;
22
21
import org .eclipse .jetty .websocket .api .UpgradeRequest ;
23
22
import org .eclipse .jetty .websocket .api .UpgradeResponse ;
24
23
import org .eclipse .jetty .websocket .client .ClientUpgradeRequest ;
36
35
import org .springframework .web .reactive .socket .adapter .JettyWebSocketSession ;
37
36
38
37
/**
39
- * Jetty based implementation of {@link WebSocketClient}.
40
- *
38
+ * A {@link WebSocketClient} implementation for use with Jetty
39
+ * {@link org.eclipse.jetty.websocket.client.WebSocketClient}.
40
+ *
41
+ * <p><strong>Note: </strong> the Jetty {@code WebSocketClient} requires
42
+ * lifecycle management and must be started and stopped. This is automatically
43
+ * managed when this class is declared as a Spring bean and created with the
44
+ * default constructor. See constructor notes for more details.
45
+ *
41
46
* @author Violeta Georgieva
42
47
* @author Rossen Stoyanchev
43
48
* @since 5.0
@@ -46,34 +51,60 @@ public class JettyWebSocketClient extends WebSocketClientSupport implements WebS
46
51
47
52
private final org .eclipse .jetty .websocket .client .WebSocketClient jettyClient ;
48
53
49
- private final DataBufferFactory bufferFactory = new DefaultDataBufferFactory ();
54
+ private final boolean externallyManaged ;
55
+
56
+ private boolean running = false ;
50
57
51
58
private final Object lifecycleMonitor = new Object ();
52
59
60
+ private final DataBufferFactory bufferFactory = new DefaultDataBufferFactory ();
61
+
53
62
54
63
/**
55
- * Default constructor that creates an instance of
56
- * {@link org.eclipse.jetty.websocket.client.WebSocketClient}.
64
+ * Default constructor that creates and manages an instance of a Jetty
65
+ * {@link org.eclipse.jetty.websocket.client.WebSocketClient WebSocketClient}.
66
+ * The instance can be obtained with {@link #getJettyClient()} for further
67
+ * configuration.
68
+ *
69
+ * <p><strong>Note: </strong> When this constructor is used {@link Lifecycle}
70
+ * methods of this class are delegated to the Jetty {@code WebSocketClient}.
57
71
*/
58
72
public JettyWebSocketClient () {
59
- this (new org .eclipse .jetty .websocket .client .WebSocketClient ());
73
+ this .jettyClient = new org .eclipse .jetty .websocket .client .WebSocketClient ();
74
+ this .externallyManaged = false ;
60
75
}
61
76
62
77
/**
63
- * Constructor that accepts an existing
64
- * {@link org.eclipse.jetty.websocket.client.WebSocketClient} instance.
65
- * @param jettyClient a web socket client
78
+ * Constructor that accepts an existing instance of a Jetty
79
+ * {@link org.eclipse.jetty.websocket.client.WebSocketClient WebSocketClient}.
80
+ *
81
+ * <p><strong>Note: </strong> Use of this constructor implies the Jetty
82
+ * {@code WebSocketClient} is externally managed and hence {@link Lifecycle}
83
+ * methods of this class are not delegated to it.
66
84
*/
67
85
public JettyWebSocketClient (org .eclipse .jetty .websocket .client .WebSocketClient jettyClient ) {
68
86
this .jettyClient = jettyClient ;
87
+ this .externallyManaged = true ;
88
+ }
89
+
90
+
91
+ /**
92
+ * Return the underlying Jetty {@code WebSocketClient}.
93
+ */
94
+ public org .eclipse .jetty .websocket .client .WebSocketClient getJettyClient () {
95
+ return this .jettyClient ;
69
96
}
70
97
71
98
72
99
@ Override
73
100
public void start () {
101
+ if (this .externallyManaged ) {
102
+ return ;
103
+ }
74
104
synchronized (this .lifecycleMonitor ) {
75
105
if (!isRunning ()) {
76
106
try {
107
+ this .running = true ;
77
108
this .jettyClient .start ();
78
109
}
79
110
catch (Exception ex ) {
@@ -85,9 +116,13 @@ public void start() {
85
116
86
117
@ Override
87
118
public void stop () {
119
+ if (this .externallyManaged ) {
120
+ return ;
121
+ }
88
122
synchronized (this .lifecycleMonitor ) {
89
123
if (isRunning ()) {
90
124
try {
125
+ this .running = false ;
91
126
this .jettyClient .stop ();
92
127
}
93
128
catch (Exception ex ) {
@@ -100,7 +135,7 @@ public void stop() {
100
135
@ Override
101
136
public boolean isRunning () {
102
137
synchronized (this .lifecycleMonitor ) {
103
- return this .jettyClient . isStarted () ;
138
+ return this .running ;
104
139
}
105
140
}
106
141
@@ -131,15 +166,13 @@ private Mono<Void> executeInternal(URI url, HttpHeaders headers, WebSocketHandle
131
166
132
167
private Object createJettyHandler (URI url , WebSocketHandler handler , MonoProcessor <Void > completion ) {
133
168
return new JettyWebSocketHandlerAdapter (handler ,
134
- session -> createJettySession (url , completion , session ));
135
- }
136
-
137
- private JettyWebSocketSession createJettySession (URI url , MonoProcessor <Void > completion , Session session ) {
138
- UpgradeResponse response = session .getUpgradeResponse ();
139
- HttpHeaders responseHeaders = new HttpHeaders ();
140
- response .getHeaders ().forEach (responseHeaders ::put );
141
- HandshakeInfo info = afterHandshake (url , responseHeaders );
142
- return new JettyWebSocketSession (session , info , this .bufferFactory , completion );
169
+ session -> {
170
+ UpgradeResponse response = session .getUpgradeResponse ();
171
+ HttpHeaders responseHeaders = new HttpHeaders ();
172
+ response .getHeaders ().forEach (responseHeaders ::put );
173
+ HandshakeInfo info = afterHandshake (url , responseHeaders );
174
+ return new JettyWebSocketSession (session , info , this .bufferFactory , completion );
175
+ });
143
176
}
144
177
145
178
0 commit comments