@stomp/stompjs 7.1.1 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +129 -106
- package/bundles/stomp.umd.js +449 -205
- package/bundles/stomp.umd.js.map +1 -1
- package/bundles/stomp.umd.min.js +1 -1
- package/esm6/client.d.ts +635 -278
- package/esm6/client.js +442 -203
- package/esm6/client.js.map +1 -1
- package/esm6/stomp-config.d.ts +13 -1
- package/esm6/stomp-config.js.map +1 -1
- package/esm6/stomp-handler.d.ts +4 -1
- package/esm6/stomp-handler.js +7 -2
- package/esm6/stomp-handler.js.map +1 -1
- package/esm6/stomp-headers.d.ts +1 -1
- package/esm6/stomp-headers.js +1 -1
- package/esm6/ticker.js +2 -2
- package/esm6/ticker.js.map +1 -1
- package/esm6/types.d.ts +11 -2
- package/esm6/types.js.map +1 -1
- package/package.json +8 -8
- package/src/augment-websocket.ts +2 -2
- package/src/client.ts +662 -290
- package/src/compatibility/compat-client.ts +2 -2
- package/src/compatibility/stomp.ts +1 -1
- package/src/frame-impl.ts +6 -6
- package/src/parser.ts +4 -4
- package/src/stomp-config.ts +15 -0
- package/src/stomp-handler.ts +30 -13
- package/src/stomp-headers.ts +1 -1
- package/src/ticker.ts +8 -6
- package/src/types.ts +14 -4
package/src/client.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
ActivationState,
|
|
8
8
|
closeEventCallbackType,
|
|
9
9
|
debugFnType,
|
|
10
|
+
emptyCallbackType,
|
|
10
11
|
frameCallbackType,
|
|
11
12
|
IPublishParams,
|
|
12
13
|
IStompSocket,
|
|
@@ -30,181 +31,297 @@ declare const WebSocket: {
|
|
|
30
31
|
* STOMP Client Class.
|
|
31
32
|
*
|
|
32
33
|
* Part of `@stomp/stompjs`.
|
|
34
|
+
*
|
|
35
|
+
* This class provides a robust implementation for connecting to and interacting with a
|
|
36
|
+
* STOMP-compliant messaging broker over WebSocket. It supports STOMP versions 1.2, 1.1, and 1.0.
|
|
37
|
+
*
|
|
38
|
+
* Features:
|
|
39
|
+
* - Handles automatic reconnections.
|
|
40
|
+
* - Supports heartbeat mechanisms to detect and report communication failures.
|
|
41
|
+
* - Allows customization of connection and WebSocket behaviors through configurations.
|
|
42
|
+
* - Compatible with both browser environments and Node.js with polyfill support for WebSocket.
|
|
33
43
|
*/
|
|
34
44
|
export class Client {
|
|
35
45
|
/**
|
|
36
46
|
* The URL for the STOMP broker to connect to.
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* If
|
|
43
|
-
*
|
|
47
|
+
* Example: `"ws://broker.domain.com:15674/ws"` or `"wss://broker.domain.com:15674/ws"`.
|
|
48
|
+
*
|
|
49
|
+
* Use this property to define the broker's WebSocket endpoint.
|
|
50
|
+
* Note:
|
|
51
|
+
* - Only one of `brokerURL` or [Client#webSocketFactory]{@link Client#webSocketFactory} needs to be set.
|
|
52
|
+
* - If both are provided, [Client#webSocketFactory]{@link Client#webSocketFactory} takes precedence.
|
|
53
|
+
* - When targeting environments without native WebSocket support, refer to
|
|
54
|
+
* [Polyfills]{@link https://stomp-js.github.io/guide/stompjs/rx-stomp/ng2-stompjs/pollyfils-for-stompjs-v5.html}.
|
|
44
55
|
*/
|
|
45
56
|
public brokerURL: string | undefined;
|
|
46
57
|
|
|
47
58
|
/**
|
|
48
|
-
* STOMP versions to
|
|
59
|
+
* STOMP protocol versions to use during the handshake. By default, the client will attempt
|
|
60
|
+
* versions `1.2`, `1.1`, and `1.0` in descending order of preference.
|
|
49
61
|
*
|
|
50
62
|
* Example:
|
|
51
63
|
* ```javascript
|
|
52
|
-
*
|
|
53
|
-
*
|
|
64
|
+
* // Configure the client to only use versions 1.1 and 1.0
|
|
65
|
+
* client.stompVersions = new Versions(['1.1', '1.0']);
|
|
54
66
|
* ```
|
|
55
67
|
*/
|
|
56
68
|
public stompVersions = Versions.default;
|
|
57
69
|
|
|
58
70
|
/**
|
|
59
|
-
*
|
|
60
|
-
* If your environment does not support WebSockets natively, please refer to
|
|
61
|
-
* [Polyfills]{@link https://stomp-js.github.io/guide/stompjs/rx-stomp/ng2-stompjs/pollyfils-for-stompjs-v5.html}.
|
|
62
|
-
* If your STOMP Broker supports WebSockets, prefer setting [Client#brokerURL]{@link Client#brokerURL}.
|
|
71
|
+
* A function that returns a WebSocket or a similar object (e.g., SockJS) to establish connections.
|
|
63
72
|
*
|
|
64
|
-
*
|
|
73
|
+
* This is an alternative to [Client#brokerURL]{@link Client#brokerURL}.
|
|
74
|
+
* Using this allows finer control over WebSocket creation, especially for custom wrappers
|
|
75
|
+
* or when working in non-standard environments.
|
|
65
76
|
*
|
|
66
77
|
* Example:
|
|
67
78
|
* ```javascript
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* };
|
|
79
|
+
* client.webSocketFactory = function () {
|
|
80
|
+
* return new WebSocket("ws://my-custom-websocket-endpoint");
|
|
81
|
+
* };
|
|
82
|
+
*
|
|
83
|
+
* // Typical usage with SockJS
|
|
84
|
+
* client.webSocketFactory= function () {
|
|
85
|
+
* return new SockJS("http://broker.329broker.com/stomp");
|
|
86
|
+
* };
|
|
77
87
|
* ```
|
|
88
|
+
*
|
|
89
|
+
* Note:
|
|
90
|
+
* - If both [Client#brokerURL]{@link Client#brokerURL} and this property are set, the factory will be used.
|
|
91
|
+
* - Refer to [Polyfills Guide]{@link https://stomp-js.github.io/guide/stompjs/rx-stomp/ng2-stompjs/pollyfils-for-stompjs-v5.html}
|
|
92
|
+
* when running in environments without native WebSocket support.
|
|
78
93
|
*/
|
|
79
94
|
public webSocketFactory: (() => IStompSocket) | undefined;
|
|
80
95
|
|
|
81
96
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
97
|
+
* Timeout for establishing STOMP connection, in milliseconds.
|
|
98
|
+
*
|
|
99
|
+
* If the connection is not established within this period, the attempt will fail.
|
|
100
|
+
* The default is `0`, meaning no timeout is set for connection attempts.
|
|
101
|
+
*
|
|
102
|
+
* Example:
|
|
103
|
+
* ```javascript
|
|
104
|
+
* client.connectionTimeout = 5000; // Fail connection if not established in 5 seconds
|
|
105
|
+
* ```
|
|
84
106
|
*/
|
|
85
107
|
public connectionTimeout: number = 0;
|
|
86
108
|
|
|
87
|
-
//
|
|
88
|
-
|
|
109
|
+
// Internal timer for handling connection timeout, if set.
|
|
110
|
+
// See https://stackoverflow.com/questions/45802988/typescript-use-correct-version-of-settimeout-node-vs-window/56239226#56239226
|
|
111
|
+
private _connectionWatcher: ReturnType<typeof setTimeout> | undefined;
|
|
89
112
|
|
|
90
113
|
/**
|
|
91
|
-
*
|
|
114
|
+
* Delay (in milliseconds) between reconnection attempts if the connection drops.
|
|
115
|
+
*
|
|
116
|
+
* Set to `0` to disable automatic reconnections. The default value is `5000` ms (5 seconds).
|
|
117
|
+
*
|
|
118
|
+
* Example:
|
|
119
|
+
* ```javascript
|
|
120
|
+
* client.reconnectDelay = 3000; // Attempt reconnection every 3 seconds
|
|
121
|
+
* client.reconnectDelay = 0; // Disable automatic reconnection
|
|
122
|
+
* ```
|
|
92
123
|
*/
|
|
93
124
|
public reconnectDelay: number = 5000;
|
|
94
125
|
|
|
95
126
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
127
|
+
* The next reconnection delay, used internally.
|
|
128
|
+
* Initialized to the value of [Client#reconnectDelay]{@link Client#reconnectDelay}, and it may
|
|
129
|
+
* dynamically change based on [Client#reconnectTimeMode]{@link Client#reconnectTimeMode}.
|
|
98
130
|
*/
|
|
99
131
|
private _nextReconnectDelay: number = 0;
|
|
100
132
|
|
|
101
133
|
/**
|
|
102
|
-
* Maximum
|
|
103
|
-
*
|
|
104
|
-
*
|
|
134
|
+
* Maximum delay (in milliseconds) between reconnection attempts when using exponential backoff.
|
|
135
|
+
*
|
|
136
|
+
* Default is 15 minutes (`15 * 60 * 1000` milliseconds). If `0`, there will be no upper limit.
|
|
137
|
+
*
|
|
138
|
+
* Example:
|
|
139
|
+
* ```javascript
|
|
140
|
+
* client.maxReconnectDelay = 10000; // Maximum wait time is 10 seconds
|
|
141
|
+
* ```
|
|
105
142
|
*/
|
|
106
|
-
public maxReconnectDelay: number = 15 * 60 * 1000;
|
|
143
|
+
public maxReconnectDelay: number = 15 * 60 * 1000;
|
|
107
144
|
|
|
108
145
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
146
|
+
* Mode for determining the time interval between reconnection attempts.
|
|
147
|
+
*
|
|
148
|
+
* Available modes:
|
|
149
|
+
* - `ReconnectionTimeMode.LINEAR` (default): Fixed delays between reconnection attempts.
|
|
150
|
+
* - `ReconnectionTimeMode.EXPONENTIAL`: Delay doubles after each attempt, capped by [maxReconnectDelay]{@link Client#maxReconnectDelay}.
|
|
151
|
+
*
|
|
152
|
+
* Example:
|
|
112
153
|
* ```javascript
|
|
113
|
-
* client.
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
* maxReconnectDelay: 10000, // Optional, when provided, it will not wait more that these ms
|
|
117
|
-
* })
|
|
154
|
+
* client.reconnectTimeMode = ReconnectionTimeMode.EXPONENTIAL;
|
|
155
|
+
* client.reconnectDelay = 200; // Initial delay of 200 ms, doubles with each attempt
|
|
156
|
+
* client.maxReconnectDelay = 2 * 60 * 1000; // Cap delay at 10 minutes
|
|
118
157
|
* ```
|
|
119
158
|
*/
|
|
120
159
|
public reconnectTimeMode: ReconnectionTimeMode = ReconnectionTimeMode.LINEAR;
|
|
121
160
|
|
|
122
161
|
/**
|
|
123
|
-
*
|
|
162
|
+
* Interval (in milliseconds) for receiving heartbeat signals from the server.
|
|
163
|
+
*
|
|
164
|
+
* Specifies the expected frequency of heartbeats sent by the server. Set to `0` to disable.
|
|
165
|
+
*
|
|
166
|
+
* Example:
|
|
167
|
+
* ```javascript
|
|
168
|
+
* client.heartbeatIncoming = 10000; // Expect a heartbeat every 10 seconds
|
|
169
|
+
* ```
|
|
124
170
|
*/
|
|
125
171
|
public heartbeatIncoming: number = 10000;
|
|
126
172
|
|
|
127
173
|
/**
|
|
128
|
-
*
|
|
174
|
+
* Multiplier for adjusting tolerance when processing heartbeat signals.
|
|
175
|
+
*
|
|
176
|
+
* Tolerance level is calculated using the multiplier:
|
|
177
|
+
* `tolerance = heartbeatIncoming * heartbeatToleranceMultiplier`.
|
|
178
|
+
* This helps account for delays in network communication or variations in timings.
|
|
179
|
+
*
|
|
180
|
+
* Default value is `2`.
|
|
181
|
+
*
|
|
182
|
+
* Example:
|
|
183
|
+
* ```javascript
|
|
184
|
+
* client.heartbeatToleranceMultiplier = 2.5; // Tolerates longer delays
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
public heartbeatToleranceMultiplier: number = 2;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Interval (in milliseconds) for sending heartbeat signals to the server.
|
|
191
|
+
*
|
|
192
|
+
* Specifies how frequently heartbeats should be sent to the server. Set to `0` to disable.
|
|
193
|
+
*
|
|
194
|
+
* Example:
|
|
195
|
+
* ```javascript
|
|
196
|
+
* client.heartbeatOutgoing = 5000; // Send a heartbeat every 5 seconds
|
|
197
|
+
* ```
|
|
129
198
|
*/
|
|
130
199
|
public heartbeatOutgoing: number = 10000;
|
|
131
200
|
|
|
132
201
|
/**
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
202
|
+
* Strategy for sending outgoing heartbeats.
|
|
203
|
+
*
|
|
204
|
+
* Options:
|
|
205
|
+
* - `TickerStrategy.Worker`: Uses Web Workers for sending heartbeats (recommended for long-running or background sessions).
|
|
206
|
+
* - `TickerStrategy.Interval`: Uses standard JavaScript `setInterval` (default).
|
|
207
|
+
*
|
|
208
|
+
* Note:
|
|
209
|
+
* - If Web Workers are unavailable (e.g., in Node.js), the `Interval` strategy is used automatically.
|
|
210
|
+
* - Web Workers are preferable in browsers for reducing disconnects when tabs are in the background.
|
|
211
|
+
*
|
|
212
|
+
* Example:
|
|
213
|
+
* ```javascript
|
|
214
|
+
* client.heartbeatStrategy = TickerStrategy.Worker;
|
|
215
|
+
* ```
|
|
146
216
|
*/
|
|
147
217
|
public heartbeatStrategy: TickerStrategy = TickerStrategy.Interval;
|
|
148
218
|
|
|
149
219
|
/**
|
|
150
|
-
*
|
|
151
|
-
* It splits larger (text) packets into chunks of [maxWebSocketChunkSize]{@link Client#maxWebSocketChunkSize}.
|
|
152
|
-
* Only Java Spring brokers seem to support this mode.
|
|
220
|
+
* Enables splitting of large text WebSocket frames into smaller chunks.
|
|
153
221
|
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
* Setting it for such a broker will cause large messages to fail.
|
|
222
|
+
* This setting is enabled for brokers that support only chunked messages (e.g., Java Spring-based brokers).
|
|
223
|
+
* Default is `false`.
|
|
157
224
|
*
|
|
158
|
-
*
|
|
225
|
+
* Warning:
|
|
226
|
+
* - Should not be used with WebSocket-compliant brokers, as chunking may cause large message failures.
|
|
227
|
+
* - Binary WebSocket frames are never split.
|
|
159
228
|
*
|
|
160
|
-
*
|
|
229
|
+
* Example:
|
|
230
|
+
* ```javascript
|
|
231
|
+
* client.splitLargeFrames = true;
|
|
232
|
+
* client.maxWebSocketChunkSize = 4096; // Allow chunks of 4 KB
|
|
233
|
+
* ```
|
|
161
234
|
*/
|
|
162
235
|
public splitLargeFrames: boolean = false;
|
|
163
236
|
|
|
164
237
|
/**
|
|
165
|
-
*
|
|
166
|
-
*
|
|
238
|
+
* Maximum size (in bytes) for individual WebSocket chunks if [splitLargeFrames]{@link Client#splitLargeFrames} is enabled.
|
|
239
|
+
*
|
|
240
|
+
* Default is 8 KB (`8 * 1024` bytes). This value has no effect if [splitLargeFrames]{@link Client#splitLargeFrames} is `false`.
|
|
167
241
|
*/
|
|
168
242
|
public maxWebSocketChunkSize: number = 8 * 1024;
|
|
169
243
|
|
|
170
244
|
/**
|
|
171
|
-
*
|
|
172
|
-
* [type of WebSocket frame]{@link https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send#Parameters}
|
|
173
|
-
* is automatically decided by type of the payload.
|
|
174
|
-
* Default is `false`, which should work with all compliant brokers.
|
|
245
|
+
* Forces all WebSocket frames to use binary transport, irrespective of payload type.
|
|
175
246
|
*
|
|
176
|
-
*
|
|
247
|
+
* Default behavior determines frame type based on payload (e.g., binary data for ArrayBuffers).
|
|
248
|
+
*
|
|
249
|
+
* Example:
|
|
250
|
+
* ```javascript
|
|
251
|
+
* client.forceBinaryWSFrames = true;
|
|
252
|
+
* ```
|
|
177
253
|
*/
|
|
178
254
|
public forceBinaryWSFrames: boolean = false;
|
|
179
255
|
|
|
180
256
|
/**
|
|
181
|
-
*
|
|
182
|
-
* See issue [https://github.com/stomp-js/stompjs/issues/89]{@link https://github.com/stomp-js/stompjs/issues/89}.
|
|
183
|
-
* This makes incoming WebSocket messages invalid STOMP packets.
|
|
184
|
-
* Setting this flag attempts to reverse the damage by appending a NULL.
|
|
185
|
-
* If the broker splits a large message into multiple WebSocket messages,
|
|
186
|
-
* this flag will cause data loss and abnormal termination of connection.
|
|
257
|
+
* Workaround for a React Native WebSocket bug, where messages containing `NULL` are chopped.
|
|
187
258
|
*
|
|
188
|
-
*
|
|
259
|
+
* Enabling this appends a `NULL` character to incoming frames to ensure they remain valid STOMP packets.
|
|
260
|
+
*
|
|
261
|
+
* Warning:
|
|
262
|
+
* - For brokers that split large messages, this may cause data loss or connection termination.
|
|
263
|
+
*
|
|
264
|
+
* Example:
|
|
265
|
+
* ```javascript
|
|
266
|
+
* client.appendMissingNULLonIncoming = true;
|
|
267
|
+
* ```
|
|
189
268
|
*/
|
|
190
269
|
public appendMissingNULLonIncoming: boolean = false;
|
|
191
270
|
|
|
192
271
|
/**
|
|
193
|
-
*
|
|
272
|
+
* Provides access to the underlying WebSocket instance.
|
|
273
|
+
* This property is **read-only**.
|
|
274
|
+
*
|
|
275
|
+
* Example:
|
|
276
|
+
* ```javascript
|
|
277
|
+
* const webSocket = client.webSocket;
|
|
278
|
+
* if (webSocket) {
|
|
279
|
+
* console.log('WebSocket is connected:', webSocket.readyState === WebSocket.OPEN);
|
|
280
|
+
* }
|
|
281
|
+
* ```
|
|
282
|
+
*
|
|
283
|
+
* **Caution:**
|
|
284
|
+
* Directly interacting with the WebSocket instance (e.g., sending or receiving frames)
|
|
285
|
+
* can interfere with the proper functioning of this library. Such actions may cause
|
|
286
|
+
* unexpected behavior, disconnections, or invalid state in the library's internal mechanisms.
|
|
287
|
+
*
|
|
288
|
+
* Instead, use the library's provided methods to manage STOMP communication.
|
|
289
|
+
*
|
|
290
|
+
* @returns The WebSocket instance used by the STOMP handler, or `undefined` if not connected.
|
|
194
291
|
*/
|
|
195
292
|
get webSocket(): IStompSocket | undefined {
|
|
196
293
|
return this._stompHandler?._webSocket;
|
|
197
294
|
}
|
|
198
295
|
|
|
199
296
|
/**
|
|
200
|
-
* Connection headers
|
|
201
|
-
*
|
|
202
|
-
*
|
|
297
|
+
* Connection headers to be sent during the connection handshake.
|
|
298
|
+
*
|
|
299
|
+
* Keys like `login`, `passcode`, and `host` are commonly expected for most brokers.
|
|
300
|
+
* Although STOMP 1.2 specifies these keys as mandatory, consult your broker's documentation
|
|
301
|
+
* for additional requirements or alternative header usage.
|
|
302
|
+
*
|
|
303
|
+
* Example:
|
|
304
|
+
* ```javascript
|
|
305
|
+
* client.connectHeaders = {
|
|
306
|
+
* login: 'my-username',
|
|
307
|
+
* passcode: 'my-password',
|
|
308
|
+
* host: 'my-vhost'
|
|
309
|
+
* };
|
|
310
|
+
* ```
|
|
203
311
|
*/
|
|
204
312
|
public connectHeaders: StompHeaders;
|
|
205
313
|
|
|
206
314
|
/**
|
|
207
|
-
*
|
|
315
|
+
* Allows customization of the disconnection headers.
|
|
316
|
+
*
|
|
317
|
+
* Any changes made during an active session will also be applied immediately.
|
|
318
|
+
*
|
|
319
|
+
* Example:
|
|
320
|
+
* ```javascript
|
|
321
|
+
* client.disconnectHeaders = {
|
|
322
|
+
* receipt: 'custom-receipt-id'
|
|
323
|
+
* };
|
|
324
|
+
* ```
|
|
208
325
|
*/
|
|
209
326
|
get disconnectHeaders(): StompHeaders {
|
|
210
327
|
return this._disconnectHeaders;
|
|
@@ -219,139 +336,272 @@ export class Client {
|
|
|
219
336
|
private _disconnectHeaders: StompHeaders;
|
|
220
337
|
|
|
221
338
|
/**
|
|
222
|
-
*
|
|
223
|
-
* It is useful for receiving messages sent to RabbitMQ temporary queues.
|
|
339
|
+
* Callback invoked for any unhandled messages received from the broker.
|
|
224
340
|
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
341
|
+
* This is particularly useful for handling messages sent to RabbitMQ temporary queues
|
|
342
|
+
* or other queues where no explicit subscription exists. It can also be triggered
|
|
343
|
+
* by stray messages received while a subscription is being unsubscribed.
|
|
228
344
|
*
|
|
229
|
-
*
|
|
345
|
+
* Usage:
|
|
346
|
+
* ```javascript
|
|
347
|
+
* client.onUnhandledMessage = (message) => {
|
|
348
|
+
* console.log('Unhandled message:', message);
|
|
349
|
+
* };
|
|
350
|
+
* ```
|
|
351
|
+
*
|
|
352
|
+
* @param message The actual {@link IMessage} received.
|
|
230
353
|
*/
|
|
231
354
|
public onUnhandledMessage: messageCallbackType;
|
|
232
355
|
|
|
233
356
|
/**
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
* [Client#watchForReceipt]{@link Client#watchForReceipt}
|
|
357
|
+
* Callback invoked when the broker sends a receipt indicating the completion
|
|
358
|
+
* of an operation. Receipts are typically requested using the
|
|
359
|
+
* [Client#watchForReceipt]{@link Client#watchForReceipt} function.
|
|
237
360
|
*
|
|
238
|
-
*
|
|
361
|
+
* Usage Example:
|
|
362
|
+
* See [Client#watchForReceipt]{@link Client#watchForReceipt}.
|
|
363
|
+
*
|
|
364
|
+
* @param frame The actual {@link IFrame} received from the broker.
|
|
239
365
|
*/
|
|
240
366
|
public onUnhandledReceipt: frameCallbackType;
|
|
241
367
|
|
|
242
368
|
/**
|
|
243
|
-
*
|
|
369
|
+
* Callback invoked when a frame of an unknown or unexpected type is received
|
|
370
|
+
* from the broker.
|
|
371
|
+
*
|
|
372
|
+
* This is intended as a fallback for handling unexpected or unsupported frames
|
|
373
|
+
* sent by the broker.
|
|
374
|
+
*
|
|
375
|
+
* Usage:
|
|
376
|
+
* ```javascript
|
|
377
|
+
* client.onUnhandledFrame = (frame) => {
|
|
378
|
+
* console.warn('Unhandled frame received:', frame);
|
|
379
|
+
* };
|
|
380
|
+
* ```
|
|
244
381
|
*
|
|
245
|
-
* The actual {@link IFrame}
|
|
382
|
+
* @param frame The actual {@link IFrame} received from the broker.
|
|
246
383
|
*/
|
|
247
384
|
public onUnhandledFrame: frameCallbackType;
|
|
248
385
|
|
|
249
386
|
/**
|
|
250
|
-
*
|
|
387
|
+
* Callback invoked when a heartbeat message is received from the STOMP broker.
|
|
388
|
+
*
|
|
389
|
+
* Heartbeats ensure that the connection remains active and responsive. This callback
|
|
390
|
+
* is executed on every received heartbeat. It is useful for monitoring connection health
|
|
391
|
+
* or logging heartbeat activity.
|
|
392
|
+
*
|
|
393
|
+
* **Note**: The library handles heartbeats internally to maintain and verify connection status.
|
|
394
|
+
* Implementing this callback is optional and primarily for custom monitoring or debugging.
|
|
395
|
+
*
|
|
396
|
+
* Usage:
|
|
397
|
+
* ```javascript
|
|
398
|
+
* client.onHeartbeatReceived = () => {
|
|
399
|
+
* console.log('Heartbeat received');
|
|
400
|
+
* };
|
|
401
|
+
* ```
|
|
402
|
+
*/
|
|
403
|
+
public onHeartbeatReceived: emptyCallbackType;
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Callback invoked when no heartbeat is received from the broker within
|
|
407
|
+
* the acceptable interval, indicating a potential communication issue or connection failure.
|
|
408
|
+
*
|
|
409
|
+
* This callback is triggered when the heartbeat interval defined by `heartbeatIncoming`
|
|
410
|
+
* elapses without a received heartbeat.
|
|
411
|
+
*
|
|
412
|
+
* **Note**: The library handles this condition internally and takes appropriate
|
|
413
|
+
* actions, such as marking the connection as failed. This callback is available
|
|
414
|
+
* for implementing custom recovery strategies or additional notifications.
|
|
415
|
+
*
|
|
416
|
+
* Usage:
|
|
417
|
+
* ```javascript
|
|
418
|
+
* client.onHeartbeatLost = () => {
|
|
419
|
+
* console.error('Lost connection to the broker');
|
|
420
|
+
* };
|
|
421
|
+
* ```
|
|
422
|
+
*/
|
|
423
|
+
public onHeartbeatLost: emptyCallbackType;
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Indicates whether there is an active connection to the STOMP broker.
|
|
427
|
+
*
|
|
428
|
+
* Usage:
|
|
429
|
+
* ```javascript
|
|
430
|
+
* if (client.connected) {
|
|
431
|
+
* console.log('Client is connected to the broker.');
|
|
432
|
+
* } else {
|
|
433
|
+
* console.log('No connection to the broker.');
|
|
434
|
+
* }
|
|
435
|
+
* ```
|
|
436
|
+
*
|
|
437
|
+
* @returns `true` if the client is currently connected, `false` otherwise.
|
|
251
438
|
*/
|
|
252
439
|
get connected(): boolean {
|
|
253
440
|
return !!this._stompHandler && this._stompHandler.connected;
|
|
254
441
|
}
|
|
255
442
|
|
|
256
443
|
/**
|
|
257
|
-
* Callback
|
|
444
|
+
* Callback executed before initiating a connection to the STOMP broker.
|
|
445
|
+
*
|
|
446
|
+
* This callback allows users to modify connection options dynamically,
|
|
447
|
+
* such as updating credentials or connection parameters, before the connection is made.
|
|
258
448
|
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
449
|
+
* As of version 5.1, this callback supports `async/await`, enabling seamless integration
|
|
450
|
+
* with asynchronous operations, such as fetching tokens or credentials.
|
|
261
451
|
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
452
|
+
* Example:
|
|
453
|
+
* ```javascript
|
|
454
|
+
* client.beforeConnect = async () => {
|
|
455
|
+
* const token = await fetchToken();
|
|
456
|
+
* client.connectHeaders = { Authorization: `Bearer ${token}` };
|
|
457
|
+
* };
|
|
458
|
+
* ```
|
|
269
459
|
*/
|
|
270
460
|
public beforeConnect: (client: Client) => void | Promise<void>;
|
|
271
461
|
|
|
272
462
|
/**
|
|
273
|
-
* Callback
|
|
463
|
+
* Callback executed upon every successful connection to the STOMP broker.
|
|
464
|
+
*
|
|
465
|
+
* This callback is invoked after the connection is established and the CONNECTED frame
|
|
466
|
+
* is received from the broker. It provides access to the broker's response frame,
|
|
467
|
+
* allowing users to parse its headers or other data.
|
|
274
468
|
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
469
|
+
* Example:
|
|
470
|
+
* ```javascript
|
|
471
|
+
* client.onConnect = (frame) => {
|
|
472
|
+
* console.log('Connected to broker, session ID:', frame.headers['session']);
|
|
473
|
+
* };
|
|
474
|
+
* ```
|
|
277
475
|
*/
|
|
278
476
|
public onConnect: frameCallbackType;
|
|
279
477
|
|
|
280
478
|
/**
|
|
281
|
-
* Callback
|
|
282
|
-
* the STOMP broker disconnected due to an error.
|
|
479
|
+
* Callback executed upon successful disconnection from the STOMP broker.
|
|
283
480
|
*
|
|
284
|
-
* The
|
|
481
|
+
* The callback is invoked when the DISCONNECT receipt is received from the broker.
|
|
482
|
+
* Note that due to the design of the STOMP protocol or communication interrupts, the
|
|
483
|
+
* DISCONNECT receipt may not always be received. For handling such cases, use
|
|
484
|
+
* [Client#onWebSocketClose]{@link Client#onWebSocketClose}.
|
|
285
485
|
*
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
*
|
|
486
|
+
* Example:
|
|
487
|
+
* ```javascript
|
|
488
|
+
* client.onDisconnect = (frame) => {
|
|
489
|
+
* console.log('Disconnected successfully');
|
|
490
|
+
* };
|
|
491
|
+
* ```
|
|
290
492
|
*/
|
|
291
493
|
public onDisconnect: frameCallbackType;
|
|
292
494
|
|
|
293
495
|
/**
|
|
294
|
-
* Callback
|
|
295
|
-
*
|
|
296
|
-
*
|
|
496
|
+
* Callback executed when an ERROR frame is received from the STOMP broker.
|
|
497
|
+
*
|
|
498
|
+
* Receiving an ERROR frame typically indicates a problem with the subscription,
|
|
499
|
+
* message format, or protocol violation. The broker will usually close the connection
|
|
500
|
+
* after sending an ERROR frame.
|
|
297
501
|
*
|
|
298
|
-
*
|
|
502
|
+
* Example:
|
|
503
|
+
* ```javascript
|
|
504
|
+
* client.onStompError = (frame) => {
|
|
505
|
+
* console.error('Broker reported an error:', frame.body);
|
|
506
|
+
* };
|
|
507
|
+
* ```
|
|
299
508
|
*/
|
|
300
509
|
public onStompError: frameCallbackType;
|
|
301
510
|
|
|
302
511
|
/**
|
|
303
|
-
* Callback
|
|
512
|
+
* Callback executed when the underlying WebSocket is closed.
|
|
513
|
+
*
|
|
514
|
+
* This can occur due to various reasons, such as network interruptions or broker shutdown.
|
|
515
|
+
* The callback provides the WebSocket [CloseEvent]{@link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent},
|
|
516
|
+
* which contains details about the closure.
|
|
304
517
|
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
518
|
+
* Example:
|
|
519
|
+
* ```javascript
|
|
520
|
+
* client.onWebSocketClose = (event) => {
|
|
521
|
+
* console.log('WebSocket closed. Code:', event.code);
|
|
522
|
+
* };
|
|
523
|
+
* ```
|
|
307
524
|
*/
|
|
308
525
|
public onWebSocketClose: closeEventCallbackType;
|
|
309
526
|
|
|
310
527
|
/**
|
|
311
|
-
* Callback
|
|
528
|
+
* Callback executed when the underlying WebSocket raises an error.
|
|
312
529
|
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
530
|
+
* This callback provides an [Event]{@link https://developer.mozilla.org/en-US/docs/Web/API/Event}
|
|
531
|
+
* representing the error raised by the WebSocket.
|
|
532
|
+
*
|
|
533
|
+
* Example:
|
|
534
|
+
* ```javascript
|
|
535
|
+
* client.onWebSocketError = (event) => {
|
|
536
|
+
* console.error('WebSocket error:', event);
|
|
537
|
+
* };
|
|
538
|
+
* ```
|
|
315
539
|
*/
|
|
316
540
|
public onWebSocketError: wsErrorCallbackType;
|
|
317
541
|
|
|
318
542
|
/**
|
|
319
|
-
*
|
|
320
|
-
* When unset, it logs headers of the parsed frames.
|
|
543
|
+
* Enable or disable logging of the raw communication with the broker.
|
|
321
544
|
*
|
|
322
|
-
*
|
|
545
|
+
* When enabled, it logs the raw frames exchanged with the broker. If disabled,
|
|
546
|
+
* only the headers of the parsed frames will be logged.
|
|
323
547
|
*
|
|
324
|
-
* **Caution
|
|
548
|
+
* **Caution**: Raw communication frames must contain valid UTF-8 strings,
|
|
549
|
+
* as any non-compliant data can cause errors in the logging process.
|
|
550
|
+
*
|
|
551
|
+
* Changes to this setting will take effect during the next broker reconnect.
|
|
552
|
+
*
|
|
553
|
+
* Example:
|
|
554
|
+
* ```javascript
|
|
555
|
+
* client.logRawCommunication = true; // Enable logging raw communication
|
|
556
|
+
* ```
|
|
325
557
|
*/
|
|
326
558
|
public logRawCommunication: boolean;
|
|
327
559
|
|
|
328
560
|
/**
|
|
329
|
-
*
|
|
561
|
+
* Set a custom debug function to capture debug messages.
|
|
330
562
|
*
|
|
563
|
+
* By default, debug messages are discarded. To log messages to the console, you can use:
|
|
331
564
|
* ```javascript
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
565
|
+
* client.debug = (str) => {
|
|
566
|
+
* console.log(str);
|
|
567
|
+
* };
|
|
335
568
|
* ```
|
|
336
569
|
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
570
|
+
* **Note**: This method does not support configurable log levels, and the output can be
|
|
571
|
+
* verbose. Be cautious as debug messages may contain sensitive information, such as
|
|
572
|
+
* credentials or tokens.
|
|
340
573
|
*/
|
|
341
574
|
public debug: debugFnType;
|
|
342
575
|
|
|
343
576
|
/**
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
577
|
+
* Instruct the library to immediately terminate the socket on communication failures, even
|
|
578
|
+
* before the WebSocket is completely closed.
|
|
579
|
+
*
|
|
580
|
+
* This is particularly useful in browser environments where WebSocket closure may get delayed,
|
|
581
|
+
* causing prolonged reconnection intervals under certain failure conditions.
|
|
582
|
+
*
|
|
583
|
+
*
|
|
584
|
+
* Example:
|
|
585
|
+
* ```javascript
|
|
586
|
+
* client.discardWebsocketOnCommFailure = true; // Enable aggressive closing of WebSocket
|
|
587
|
+
* ```
|
|
588
|
+
*
|
|
589
|
+
* Default value: `false`.
|
|
350
590
|
*/
|
|
351
591
|
public discardWebsocketOnCommFailure: boolean = false;
|
|
352
592
|
|
|
353
593
|
/**
|
|
354
|
-
* version of STOMP protocol negotiated with the server
|
|
594
|
+
* The version of the STOMP protocol negotiated with the server during connection.
|
|
595
|
+
*
|
|
596
|
+
* This is a **read-only** property and reflects the negotiated protocol version after
|
|
597
|
+
* a successful connection.
|
|
598
|
+
*
|
|
599
|
+
* Example:
|
|
600
|
+
* ```javascript
|
|
601
|
+
* console.log('Connected STOMP version:', client.connectedVersion);
|
|
602
|
+
* ```
|
|
603
|
+
*
|
|
604
|
+
* @returns The negotiated STOMP protocol version or `undefined` if not connected.
|
|
355
605
|
*/
|
|
356
606
|
get connectedVersion(): string | undefined {
|
|
357
607
|
return this._stompHandler ? this._stompHandler.connectedVersion : undefined;
|
|
@@ -360,16 +610,38 @@ export class Client {
|
|
|
360
610
|
private _stompHandler: StompHandler | undefined;
|
|
361
611
|
|
|
362
612
|
/**
|
|
363
|
-
*
|
|
613
|
+
* Indicates whether the client is currently active.
|
|
614
|
+
*
|
|
615
|
+
* A client is considered active if it is connected or actively attempting to reconnect.
|
|
616
|
+
*
|
|
617
|
+
* Example:
|
|
618
|
+
* ```javascript
|
|
619
|
+
* if (client.active) {
|
|
620
|
+
* console.log('The client is active.');
|
|
621
|
+
* } else {
|
|
622
|
+
* console.log('The client is inactive.');
|
|
623
|
+
* }
|
|
624
|
+
* ```
|
|
625
|
+
*
|
|
626
|
+
* @returns `true` if the client is active, otherwise `false`.
|
|
364
627
|
*/
|
|
365
628
|
get active(): boolean {
|
|
366
629
|
return this.state === ActivationState.ACTIVE;
|
|
367
630
|
}
|
|
368
631
|
|
|
369
632
|
/**
|
|
370
|
-
*
|
|
633
|
+
* Callback invoked whenever the client's state changes.
|
|
634
|
+
*
|
|
635
|
+
* This callback can be used to monitor transitions between various states, such as `ACTIVE`,
|
|
636
|
+
* `INACTIVE`, or `DEACTIVATING`. Note that in some scenarios, the client may transition
|
|
637
|
+
* directly from `ACTIVE` to `INACTIVE` without entering the `DEACTIVATING` state.
|
|
371
638
|
*
|
|
372
|
-
*
|
|
639
|
+
* Example:
|
|
640
|
+
* ```javascript
|
|
641
|
+
* client.onChangeState = (state) => {
|
|
642
|
+
* console.log(`Client state changed to: ${state}`);
|
|
643
|
+
* };
|
|
644
|
+
* ```
|
|
373
645
|
*/
|
|
374
646
|
public onChangeState: (state: ActivationState) => void;
|
|
375
647
|
|
|
@@ -379,17 +651,35 @@ export class Client {
|
|
|
379
651
|
}
|
|
380
652
|
|
|
381
653
|
/**
|
|
382
|
-
*
|
|
654
|
+
* Current activation state of the client.
|
|
655
|
+
*
|
|
656
|
+
* Possible states:
|
|
657
|
+
* - `ActivationState.ACTIVE`: Client is connected or actively attempting to connect.
|
|
658
|
+
* - `ActivationState.INACTIVE`: Client is disconnected and not attempting to reconnect.
|
|
659
|
+
* - `ActivationState.DEACTIVATING`: Client is in the process of disconnecting.
|
|
383
660
|
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
661
|
+
* Note: The client may transition directly from `ACTIVE` to `INACTIVE` without entering
|
|
662
|
+
* the `DEACTIVATING` state.
|
|
386
663
|
*/
|
|
387
664
|
public state: ActivationState = ActivationState.INACTIVE;
|
|
388
665
|
|
|
389
666
|
private _reconnector: any;
|
|
390
667
|
|
|
391
668
|
/**
|
|
392
|
-
*
|
|
669
|
+
* Constructs a new STOMP client instance.
|
|
670
|
+
*
|
|
671
|
+
* The constructor initializes default values and sets up no-op callbacks for all events.
|
|
672
|
+
* Configuration can be passed during construction, or updated later using `configure`.
|
|
673
|
+
*
|
|
674
|
+
* Example:
|
|
675
|
+
* ```javascript
|
|
676
|
+
* const client = new Client({
|
|
677
|
+
* brokerURL: 'wss://broker.example.com',
|
|
678
|
+
* reconnectDelay: 5000
|
|
679
|
+
* });
|
|
680
|
+
* ```
|
|
681
|
+
*
|
|
682
|
+
* @param conf Optional configuration object to initialize the client with.
|
|
393
683
|
*/
|
|
394
684
|
constructor(conf: StompConfig = {}) {
|
|
395
685
|
// No op callbacks
|
|
@@ -401,6 +691,8 @@ export class Client {
|
|
|
401
691
|
this.onUnhandledMessage = noOp;
|
|
402
692
|
this.onUnhandledReceipt = noOp;
|
|
403
693
|
this.onUnhandledFrame = noOp;
|
|
694
|
+
this.onHeartbeatReceived = noOp;
|
|
695
|
+
this.onHeartbeatLost = noOp;
|
|
404
696
|
this.onStompError = noOp;
|
|
405
697
|
this.onWebSocketClose = noOp;
|
|
406
698
|
this.onWebSocketError = noOp;
|
|
@@ -416,8 +708,24 @@ export class Client {
|
|
|
416
708
|
}
|
|
417
709
|
|
|
418
710
|
/**
|
|
419
|
-
*
|
|
711
|
+
* Updates the client's configuration.
|
|
712
|
+
*
|
|
713
|
+
* All properties in the provided configuration object will override the current settings.
|
|
714
|
+
*
|
|
715
|
+
* Additionally, a warning is logged if `maxReconnectDelay` is configured to a
|
|
716
|
+
* value lower than `reconnectDelay`, and `maxReconnectDelay` is adjusted to match `reconnectDelay`.
|
|
717
|
+
*
|
|
718
|
+
* Example:
|
|
719
|
+
* ```javascript
|
|
720
|
+
* client.configure({
|
|
721
|
+
* reconnectDelay: 3000,
|
|
722
|
+
* maxReconnectDelay: 10000
|
|
723
|
+
* });
|
|
724
|
+
* ```
|
|
725
|
+
*
|
|
726
|
+
* @param conf Configuration object containing the new settings.
|
|
420
727
|
*/
|
|
728
|
+
|
|
421
729
|
public configure(conf: StompConfig): void {
|
|
422
730
|
// bulk assign all properties to this
|
|
423
731
|
(Object as any).assign(this, conf);
|
|
@@ -435,12 +743,20 @@ export class Client {
|
|
|
435
743
|
}
|
|
436
744
|
|
|
437
745
|
/**
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
* is
|
|
746
|
+
* Activates the client, initiating a connection to the STOMP broker.
|
|
747
|
+
*
|
|
748
|
+
* On activation, the client attempts to connect and sets its state to `ACTIVE`. If the connection
|
|
749
|
+
* is lost, it will automatically retry based on `reconnectDelay` or `maxReconnectDelay`. If
|
|
750
|
+
* `reconnectTimeMode` is set to `EXPONENTIAL`, the reconnect delay increases exponentially.
|
|
751
|
+
*
|
|
752
|
+
* To stop reconnection attempts and disconnect, call [Client#deactivate]{@link Client#deactivate}.
|
|
753
|
+
*
|
|
754
|
+
* Example:
|
|
755
|
+
* ```javascript
|
|
756
|
+
* client.activate(); // Connect to the broker
|
|
757
|
+
* ```
|
|
442
758
|
*
|
|
443
|
-
*
|
|
759
|
+
* If the client is currently `DEACTIVATING`, connection is delayed until the deactivation process completes.
|
|
444
760
|
*/
|
|
445
761
|
public activate(): void {
|
|
446
762
|
const _activate = () => {
|
|
@@ -513,6 +829,7 @@ export class Client {
|
|
|
513
829
|
connectHeaders: this.connectHeaders,
|
|
514
830
|
disconnectHeaders: this._disconnectHeaders,
|
|
515
831
|
heartbeatIncoming: this.heartbeatIncoming,
|
|
832
|
+
heartbeatGracePeriods: this.heartbeatToleranceMultiplier,
|
|
516
833
|
heartbeatOutgoing: this.heartbeatOutgoing,
|
|
517
834
|
heartbeatStrategy: this.heartbeatStrategy,
|
|
518
835
|
splitLargeFrames: this.splitLargeFrames,
|
|
@@ -572,6 +889,12 @@ export class Client {
|
|
|
572
889
|
onUnhandledFrame: frame => {
|
|
573
890
|
this.onUnhandledFrame(frame);
|
|
574
891
|
},
|
|
892
|
+
onHeartbeatReceived: () => {
|
|
893
|
+
this.onHeartbeatReceived();
|
|
894
|
+
},
|
|
895
|
+
onHeartbeatLost: () => {
|
|
896
|
+
this.onHeartbeatLost();
|
|
897
|
+
},
|
|
575
898
|
});
|
|
576
899
|
|
|
577
900
|
this._stompHandler.start();
|
|
@@ -619,27 +942,36 @@ export class Client {
|
|
|
619
942
|
}
|
|
620
943
|
|
|
621
944
|
/**
|
|
622
|
-
*
|
|
623
|
-
* Appropriate callbacks will be invoked if there is an underlying STOMP connection.
|
|
945
|
+
* Disconnects the client and stops the automatic reconnection loop.
|
|
624
946
|
*
|
|
625
|
-
*
|
|
626
|
-
*
|
|
947
|
+
* If there is an active STOMP connection at the time of invocation, the appropriate callbacks
|
|
948
|
+
* will be triggered during the shutdown sequence. Once deactivated, the client will enter the
|
|
949
|
+
* `INACTIVE` state, and no further reconnection attempts will be made.
|
|
627
950
|
*
|
|
628
|
-
*
|
|
629
|
-
*
|
|
951
|
+
* **Behavior**:
|
|
952
|
+
* - If there is no active WebSocket connection, this method resolves immediately.
|
|
953
|
+
* - If there is an active connection, the method waits for the underlying WebSocket
|
|
954
|
+
* to properly close before resolving.
|
|
955
|
+
* - Multiple calls to this method are safe. Each invocation resolves upon completion.
|
|
956
|
+
* - To reactivate, call [Client#activate]{@link Client#activate}.
|
|
630
957
|
*
|
|
631
|
-
*
|
|
958
|
+
* **Experimental Option:**
|
|
959
|
+
* - By specifying the `force: true` option, the WebSocket connection is discarded immediately,
|
|
960
|
+
* bypassing both the STOMP and WebSocket shutdown sequences.
|
|
961
|
+
* - **Caution:** Using `force: true` may leave the WebSocket in an inconsistent state,
|
|
962
|
+
* and brokers may not immediately detect the termination.
|
|
632
963
|
*
|
|
633
|
-
*
|
|
634
|
-
*
|
|
635
|
-
*
|
|
636
|
-
*
|
|
637
|
-
* Using this mode can speed up.
|
|
638
|
-
* When this mode is used, the actual Websocket may linger for a while
|
|
639
|
-
* and the broker may not realize that the connection is no longer in use.
|
|
964
|
+
* Example:
|
|
965
|
+
* ```javascript
|
|
966
|
+
* // Graceful disconnect
|
|
967
|
+
* await client.deactivate();
|
|
640
968
|
*
|
|
641
|
-
*
|
|
642
|
-
*
|
|
969
|
+
* // Forced disconnect to speed up shutdown when the connection is stale
|
|
970
|
+
* await client.deactivate({ force: true });
|
|
971
|
+
* ```
|
|
972
|
+
*
|
|
973
|
+
* @param options Configuration options for deactivation. Use `force: true` for immediate shutdown.
|
|
974
|
+
* @returns A Promise that resolves when the deactivation process completes.
|
|
643
975
|
*/
|
|
644
976
|
public async deactivate(options: { force?: boolean } = {}): Promise<void> {
|
|
645
977
|
const force: boolean = options.force || false;
|
|
@@ -692,10 +1024,18 @@ export class Client {
|
|
|
692
1024
|
}
|
|
693
1025
|
|
|
694
1026
|
/**
|
|
695
|
-
*
|
|
696
|
-
*
|
|
697
|
-
*
|
|
698
|
-
*
|
|
1027
|
+
* Forces a disconnect by directly closing the WebSocket.
|
|
1028
|
+
*
|
|
1029
|
+
* Unlike a normal disconnect, this does not send a DISCONNECT sequence to the broker but
|
|
1030
|
+
* instead closes the WebSocket connection directly. After forcing a disconnect, the client
|
|
1031
|
+
* will automatically attempt to reconnect based on its `reconnectDelay` configuration.
|
|
1032
|
+
*
|
|
1033
|
+
* **Note:** To prevent further reconnect attempts, call [Client#deactivate]{@link Client#deactivate}.
|
|
1034
|
+
*
|
|
1035
|
+
* Example:
|
|
1036
|
+
* ```javascript
|
|
1037
|
+
* client.forceDisconnect();
|
|
1038
|
+
* ```
|
|
699
1039
|
*/
|
|
700
1040
|
public forceDisconnect() {
|
|
701
1041
|
if (this._stompHandler) {
|
|
@@ -711,39 +1051,38 @@ export class Client {
|
|
|
711
1051
|
}
|
|
712
1052
|
|
|
713
1053
|
/**
|
|
714
|
-
*
|
|
715
|
-
* and naming of destinations.
|
|
716
|
-
*
|
|
717
|
-
* STOMP protocol specifies and suggests some headers and also allows broker-specific headers.
|
|
718
|
-
*
|
|
719
|
-
* `body` must be String.
|
|
720
|
-
* You will need to covert the payload to string in case it is not string (e.g. JSON).
|
|
1054
|
+
* Sends a message to the specified destination on the STOMP broker.
|
|
721
1055
|
*
|
|
722
|
-
*
|
|
723
|
-
* [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array).
|
|
724
|
-
* Sometimes brokers may not support binary frames out of the box.
|
|
725
|
-
* Please check your broker documentation.
|
|
1056
|
+
* The `body` must be a `string`. For non-string payloads (e.g., JSON), encode it as a string before sending.
|
|
1057
|
+
* If sending binary data, use the `binaryBody` parameter as a [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array).
|
|
726
1058
|
*
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
*
|
|
1059
|
+
* **Content-Length Behavior**:
|
|
1060
|
+
* - For non-binary messages, the `content-length` header is added by default.
|
|
1061
|
+
* - The `content-length` header can be skipped for text frames by setting `skipContentLengthHeader: true` in the parameters.
|
|
1062
|
+
* - For binary messages, the `content-length` header is always included.
|
|
730
1063
|
*
|
|
731
|
-
*
|
|
732
|
-
*
|
|
1064
|
+
* **Notes**:
|
|
1065
|
+
* - Ensure that brokers support binary frames before using `binaryBody`.
|
|
1066
|
+
* - Sending messages with NULL octets and missing `content-length` headers can cause brokers to disconnect and throw errors.
|
|
733
1067
|
*
|
|
1068
|
+
* Example:
|
|
734
1069
|
* ```javascript
|
|
735
|
-
*
|
|
736
|
-
*
|
|
737
|
-
*
|
|
738
|
-
*
|
|
739
|
-
*
|
|
740
|
-
*
|
|
741
|
-
*
|
|
742
|
-
*
|
|
743
|
-
*
|
|
744
|
-
*
|
|
745
|
-
*
|
|
746
|
-
*
|
|
1070
|
+
* // Basic text message
|
|
1071
|
+
* client.publish({ destination: "/queue/test", body: "Hello, STOMP" });
|
|
1072
|
+
*
|
|
1073
|
+
* // Text message with additional headers
|
|
1074
|
+
* client.publish({ destination: "/queue/test", headers: { priority: 9 }, body: "Hello, STOMP" });
|
|
1075
|
+
*
|
|
1076
|
+
* // Skip content-length header
|
|
1077
|
+
* client.publish({ destination: "/queue/test", body: "Hello, STOMP", skipContentLengthHeader: true });
|
|
1078
|
+
*
|
|
1079
|
+
* // Binary message
|
|
1080
|
+
* const binaryData = new Uint8Array([1, 2, 3, 4]);
|
|
1081
|
+
* client.publish({
|
|
1082
|
+
* destination: '/topic/special',
|
|
1083
|
+
* binaryBody: binaryData,
|
|
1084
|
+
* headers: { 'content-type': 'application/octet-stream' }
|
|
1085
|
+
* });
|
|
747
1086
|
* ```
|
|
748
1087
|
*/
|
|
749
1088
|
public publish(params: IPublishParams) {
|
|
@@ -759,39 +1098,27 @@ export class Client {
|
|
|
759
1098
|
}
|
|
760
1099
|
|
|
761
1100
|
/**
|
|
762
|
-
*
|
|
763
|
-
* To request an acknowledgement, a `receipt` header needs to be sent with the actual request.
|
|
764
|
-
* The value (say receipt-id) for this header needs to be unique for each use.
|
|
765
|
-
* Typically, a sequence, a UUID, a random number or a combination may be used.
|
|
766
|
-
*
|
|
767
|
-
* A complaint broker will send a RECEIPT frame when an operation has actually been completed.
|
|
768
|
-
* The operation needs to be matched based on the value of the receipt-id.
|
|
1101
|
+
* Monitors for a receipt acknowledgment from the broker for specific operations.
|
|
769
1102
|
*
|
|
770
|
-
*
|
|
771
|
-
*
|
|
1103
|
+
* Add a `receipt` header to the operation (like subscribe or publish), and use this method with
|
|
1104
|
+
* the same receipt ID to detect when the broker has acknowledged the operation's completion.
|
|
772
1105
|
*
|
|
773
|
-
* The
|
|
1106
|
+
* The callback is invoked with the corresponding {@link IFrame} when the receipt is received.
|
|
774
1107
|
*
|
|
775
1108
|
* Example:
|
|
776
1109
|
* ```javascript
|
|
777
|
-
*
|
|
778
|
-
* let receiptId = randomText();
|
|
779
|
-
*
|
|
780
|
-
* client.watchForReceipt(receiptId, function() {
|
|
781
|
-
* // Will be called after server acknowledges
|
|
782
|
-
* });
|
|
1110
|
+
* const receiptId = "unique-receipt-id";
|
|
783
1111
|
*
|
|
784
|
-
*
|
|
1112
|
+
* client.watchForReceipt(receiptId, (frame) => {
|
|
1113
|
+
* console.log("Operation acknowledged by the broker:", frame);
|
|
1114
|
+
* });
|
|
785
1115
|
*
|
|
786
|
-
*
|
|
787
|
-
*
|
|
788
|
-
* receiptId = randomText();
|
|
789
|
-
*
|
|
790
|
-
* client.watchForReceipt(receiptId, function() {
|
|
791
|
-
* // Will be called after server acknowledges
|
|
792
|
-
* });
|
|
793
|
-
* client.publish({destination: TEST.destination, headers: {receipt: receiptId}, body: msg});
|
|
1116
|
+
* // Attach the receipt header to an operation
|
|
1117
|
+
* client.publish({ destination: "/queue/test", headers: { receipt: receiptId }, body: "Hello" });
|
|
794
1118
|
* ```
|
|
1119
|
+
*
|
|
1120
|
+
* @param receiptId Unique identifier for the receipt.
|
|
1121
|
+
* @param callback Callback function invoked on receiving the RECEIPT frame.
|
|
795
1122
|
*/
|
|
796
1123
|
public watchForReceipt(receiptId: string, callback: frameCallbackType): void {
|
|
797
1124
|
this._checkConnection();
|
|
@@ -800,28 +1127,33 @@ export class Client {
|
|
|
800
1127
|
}
|
|
801
1128
|
|
|
802
1129
|
/**
|
|
803
|
-
*
|
|
804
|
-
*
|
|
1130
|
+
* Subscribes to a destination on the STOMP broker.
|
|
1131
|
+
*
|
|
1132
|
+
* The callback is triggered for each message received from the subscribed destination. The message
|
|
1133
|
+
* is passed as an {@link IMessage} instance.
|
|
805
1134
|
*
|
|
806
|
-
*
|
|
807
|
-
*
|
|
1135
|
+
* **Subscription ID**:
|
|
1136
|
+
* - If no `id` is provided in `headers`, the library generates a unique subscription ID automatically.
|
|
1137
|
+
* - Provide an explicit `id` in `headers` if you wish to manage the subscription ID manually.
|
|
808
1138
|
*
|
|
1139
|
+
* Example:
|
|
809
1140
|
* ```javascript
|
|
810
|
-
*
|
|
811
|
-
*
|
|
812
|
-
*
|
|
813
|
-
* alert("got message with body " + message.body)
|
|
814
|
-
* } else {
|
|
815
|
-
* alert("got empty message");
|
|
816
|
-
* }
|
|
817
|
-
* });
|
|
1141
|
+
* const callback = (message) => {
|
|
1142
|
+
* console.log("Received message:", message.body);
|
|
1143
|
+
* };
|
|
818
1144
|
*
|
|
819
|
-
*
|
|
1145
|
+
* // Auto-generated subscription ID
|
|
1146
|
+
* const subscription = client.subscribe("/queue/test", callback);
|
|
820
1147
|
*
|
|
821
|
-
*
|
|
822
|
-
*
|
|
823
|
-
*
|
|
1148
|
+
* // Explicit subscription ID
|
|
1149
|
+
* const mySubId = "my-subscription-id";
|
|
1150
|
+
* const subscription = client.subscribe("/queue/test", callback, { id: mySubId });
|
|
824
1151
|
* ```
|
|
1152
|
+
*
|
|
1153
|
+
* @param destination Destination to subscribe to.
|
|
1154
|
+
* @param callback Function invoked for each received message.
|
|
1155
|
+
* @param headers Optional headers for subscription, such as `id`.
|
|
1156
|
+
* @returns A {@link StompSubscription} which can be used to manage the subscription.
|
|
825
1157
|
*/
|
|
826
1158
|
public subscribe(
|
|
827
1159
|
destination: string,
|
|
@@ -834,16 +1166,24 @@ export class Client {
|
|
|
834
1166
|
}
|
|
835
1167
|
|
|
836
1168
|
/**
|
|
837
|
-
*
|
|
838
|
-
* `unsubscribe()` directly on {@link StompSubscription} returned by `client.subscribe()`:
|
|
1169
|
+
* Unsubscribes from a subscription on the STOMP broker.
|
|
839
1170
|
*
|
|
1171
|
+
* Prefer using the `unsubscribe` method directly on the {@link StompSubscription} returned from `subscribe` for cleaner management:
|
|
840
1172
|
* ```javascript
|
|
841
|
-
*
|
|
842
|
-
*
|
|
843
|
-
*
|
|
1173
|
+
* const subscription = client.subscribe("/queue/test", callback);
|
|
1174
|
+
* // Unsubscribe using the subscription object
|
|
1175
|
+
* subscription.unsubscribe();
|
|
844
1176
|
* ```
|
|
845
1177
|
*
|
|
846
|
-
*
|
|
1178
|
+
* This method can also be used directly with the subscription ID.
|
|
1179
|
+
*
|
|
1180
|
+
* Example:
|
|
1181
|
+
* ```javascript
|
|
1182
|
+
* client.unsubscribe("my-subscription-id");
|
|
1183
|
+
* ```
|
|
1184
|
+
*
|
|
1185
|
+
* @param id Subscription ID to unsubscribe.
|
|
1186
|
+
* @param headers Optional headers to pass for the UNSUBSCRIBE frame.
|
|
847
1187
|
*/
|
|
848
1188
|
public unsubscribe(id: string, headers: StompHeaders = {}): void {
|
|
849
1189
|
this._checkConnection();
|
|
@@ -852,10 +1192,21 @@ export class Client {
|
|
|
852
1192
|
}
|
|
853
1193
|
|
|
854
1194
|
/**
|
|
855
|
-
*
|
|
856
|
-
* and [abort]{@link ITransaction#abort}.
|
|
1195
|
+
* Starts a new transaction. The returned {@link ITransaction} object provides
|
|
1196
|
+
* methods for [commit]{@link ITransaction#commit} and [abort]{@link ITransaction#abort}.
|
|
1197
|
+
*
|
|
1198
|
+
* If `transactionId` is not provided, the library generates a unique ID internally.
|
|
1199
|
+
*
|
|
1200
|
+
* Example:
|
|
1201
|
+
* ```javascript
|
|
1202
|
+
* const tx = client.begin(); // Auto-generated ID
|
|
1203
|
+
*
|
|
1204
|
+
* // Or explicitly specify a transaction ID
|
|
1205
|
+
* const tx = client.begin("my-transaction-id");
|
|
1206
|
+
* ```
|
|
857
1207
|
*
|
|
858
|
-
*
|
|
1208
|
+
* @param transactionId Optional transaction ID.
|
|
1209
|
+
* @returns An instance of {@link ITransaction}.
|
|
859
1210
|
*/
|
|
860
1211
|
public begin(transactionId?: string): ITransaction {
|
|
861
1212
|
this._checkConnection();
|
|
@@ -864,16 +1215,19 @@ export class Client {
|
|
|
864
1215
|
}
|
|
865
1216
|
|
|
866
1217
|
/**
|
|
867
|
-
*
|
|
868
|
-
*
|
|
869
|
-
* It is
|
|
870
|
-
*
|
|
871
|
-
*
|
|
1218
|
+
* Commits a transaction.
|
|
1219
|
+
*
|
|
1220
|
+
* It is strongly recommended to call [commit]{@link ITransaction#commit} on
|
|
1221
|
+
* the transaction object returned by [client#begin]{@link Client#begin}.
|
|
1222
|
+
*
|
|
1223
|
+
* Example:
|
|
872
1224
|
* ```javascript
|
|
873
|
-
*
|
|
874
|
-
*
|
|
875
|
-
*
|
|
1225
|
+
* const tx = client.begin();
|
|
1226
|
+
* // Perform operations under this transaction
|
|
1227
|
+
* tx.commit();
|
|
876
1228
|
* ```
|
|
1229
|
+
*
|
|
1230
|
+
* @param transactionId The ID of the transaction to commit.
|
|
877
1231
|
*/
|
|
878
1232
|
public commit(transactionId: string): void {
|
|
879
1233
|
this._checkConnection();
|
|
@@ -882,15 +1236,19 @@ export class Client {
|
|
|
882
1236
|
}
|
|
883
1237
|
|
|
884
1238
|
/**
|
|
885
|
-
*
|
|
886
|
-
*
|
|
887
|
-
*
|
|
888
|
-
*
|
|
1239
|
+
* Aborts a transaction.
|
|
1240
|
+
*
|
|
1241
|
+
* It is strongly recommended to call [abort]{@link ITransaction#abort} directly
|
|
1242
|
+
* on the transaction object returned by [client#begin]{@link Client#begin}.
|
|
1243
|
+
*
|
|
1244
|
+
* Example:
|
|
889
1245
|
* ```javascript
|
|
890
|
-
*
|
|
891
|
-
*
|
|
892
|
-
*
|
|
1246
|
+
* const tx = client.begin();
|
|
1247
|
+
* // Perform operations under this transaction
|
|
1248
|
+
* tx.abort(); // Abort the transaction
|
|
893
1249
|
* ```
|
|
1250
|
+
*
|
|
1251
|
+
* @param transactionId The ID of the transaction to abort.
|
|
894
1252
|
*/
|
|
895
1253
|
public abort(transactionId: string): void {
|
|
896
1254
|
this._checkConnection();
|
|
@@ -899,17 +1257,23 @@ export class Client {
|
|
|
899
1257
|
}
|
|
900
1258
|
|
|
901
1259
|
/**
|
|
902
|
-
*
|
|
903
|
-
* on the {@link IMessage}
|
|
904
|
-
*
|
|
1260
|
+
* Acknowledges receipt of a message. Typically, this should be done by calling
|
|
1261
|
+
* [ack]{@link IMessage#ack} directly on the {@link IMessage} instance passed
|
|
1262
|
+
* to the subscription callback.
|
|
1263
|
+
*
|
|
1264
|
+
* Example:
|
|
905
1265
|
* ```javascript
|
|
906
|
-
*
|
|
907
|
-
*
|
|
908
|
-
*
|
|
909
|
-
*
|
|
910
|
-
*
|
|
911
|
-
*
|
|
1266
|
+
* const callback = (message) => {
|
|
1267
|
+
* // Process the message
|
|
1268
|
+
* message.ack(); // Acknowledge the message
|
|
1269
|
+
* };
|
|
1270
|
+
*
|
|
1271
|
+
* client.subscribe("/queue/example", callback, { ack: "client" });
|
|
912
1272
|
* ```
|
|
1273
|
+
*
|
|
1274
|
+
* @param messageId The ID of the message to acknowledge.
|
|
1275
|
+
* @param subscriptionId The ID of the subscription.
|
|
1276
|
+
* @param headers Optional headers for the acknowledgment frame.
|
|
913
1277
|
*/
|
|
914
1278
|
public ack(
|
|
915
1279
|
messageId: string,
|
|
@@ -922,17 +1286,25 @@ export class Client {
|
|
|
922
1286
|
}
|
|
923
1287
|
|
|
924
1288
|
/**
|
|
925
|
-
*
|
|
926
|
-
*
|
|
927
|
-
*
|
|
1289
|
+
* Rejects a message (negative acknowledgment). Like acknowledgments, this should
|
|
1290
|
+
* typically be done by calling [nack]{@link IMessage#nack} directly on the {@link IMessage}
|
|
1291
|
+
* instance passed to the subscription callback.
|
|
1292
|
+
*
|
|
1293
|
+
* Example:
|
|
928
1294
|
* ```javascript
|
|
929
|
-
*
|
|
930
|
-
*
|
|
931
|
-
*
|
|
932
|
-
*
|
|
933
|
-
*
|
|
934
|
-
*
|
|
1295
|
+
* const callback = (message) => {
|
|
1296
|
+
* // Process the message
|
|
1297
|
+
* if (isError(message)) {
|
|
1298
|
+
* message.nack(); // Reject the message
|
|
1299
|
+
* }
|
|
1300
|
+
* };
|
|
1301
|
+
*
|
|
1302
|
+
* client.subscribe("/queue/example", callback, { ack: "client" });
|
|
935
1303
|
* ```
|
|
1304
|
+
*
|
|
1305
|
+
* @param messageId The ID of the message to negatively acknowledge.
|
|
1306
|
+
* @param subscriptionId The ID of the subscription.
|
|
1307
|
+
* @param headers Optional headers for the NACK frame.
|
|
936
1308
|
*/
|
|
937
1309
|
public nack(
|
|
938
1310
|
messageId: string,
|