@stomp/stompjs 6.1.2 → 7.0.0-beta1
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/bundles/stomp.umd.js +321 -304
- package/bundles/stomp.umd.min.js +1 -2
- package/esm6/augment-websocket.js +4 -3
- package/esm6/augment-websocket.js.map +1 -1
- package/esm6/client.d.ts +29 -13
- package/esm6/client.js +75 -16
- package/esm6/client.js.map +1 -1
- package/esm6/compatibility/compat-client.d.ts +26 -20
- package/esm6/compatibility/heartbeat-info.d.ts +4 -2
- package/esm6/frame-impl.d.ts +2 -2
- package/esm6/frame-impl.js +2 -1
- package/esm6/frame-impl.js.map +1 -1
- package/esm6/i-frame.js +1 -0
- package/esm6/i-message.js +1 -0
- package/esm6/i-transaction.js +1 -0
- package/esm6/index.js +3 -0
- package/esm6/index.js.map +1 -1
- package/esm6/parser.js +10 -2
- package/esm6/parser.js.map +1 -1
- package/esm6/stomp-handler.d.ts +5 -8
- package/esm6/stomp-handler.js +29 -11
- package/esm6/stomp-handler.js.map +1 -1
- package/esm6/stomp-subscription.d.ts +1 -1
- package/esm6/stomp-subscription.js +1 -7
- package/esm6/stomp-subscription.js.map +1 -1
- package/esm6/types.d.ts +28 -2
- package/esm6/types.js.map +1 -1
- package/esm6/versions.js +2 -2
- package/package.json +26 -24
- package/src/augment-websocket.ts +4 -3
- package/src/client.ts +74 -28
- package/src/frame-impl.ts +10 -6
- package/src/parser.ts +17 -5
- package/src/stomp-handler.ts +36 -20
- package/src/stomp-subscription.ts +3 -3
- package/src/types.ts +29 -2
- package/src/versions.ts +2 -2
- package/bundles/stomp.umd.js.map +0 -1
- package/bundles/stomp.umd.min.js.map +0 -1
package/src/client.ts
CHANGED
|
@@ -40,7 +40,7 @@ export class Client {
|
|
|
40
40
|
* If your environment does not support WebSockets natively, please refer to
|
|
41
41
|
* [Polyfills]{@link https://stomp-js.github.io/guide/stompjs/rx-stomp/ng2-stompjs/pollyfils-for-stompjs-v5.html}.
|
|
42
42
|
*/
|
|
43
|
-
public brokerURL: string;
|
|
43
|
+
public brokerURL: string | undefined;
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
46
|
* STOMP versions to attempt during STOMP handshake. By default versions `1.0`, `1.1`, and `1.2` are attempted.
|
|
@@ -74,7 +74,7 @@ export class Client {
|
|
|
74
74
|
* };
|
|
75
75
|
* ```
|
|
76
76
|
*/
|
|
77
|
-
public webSocketFactory: () => IStompSocket;
|
|
77
|
+
public webSocketFactory: (() => IStompSocket) | undefined;
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
80
|
* Will retry if Stomp connection is not established in specified milliseconds.
|
|
@@ -82,7 +82,8 @@ export class Client {
|
|
|
82
82
|
*/
|
|
83
83
|
public connectionTimeout: number = 0;
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
// As per https://stackoverflow.com/questions/45802988/typescript-use-correct-version-of-settimeout-node-vs-window/56239226#56239226
|
|
86
|
+
private _connectionWatcher: ReturnType<typeof setTimeout> | undefined; // Timer
|
|
86
87
|
|
|
87
88
|
/**
|
|
88
89
|
* automatically reconnect with delay in milliseconds, set to 0 to disable.
|
|
@@ -145,8 +146,8 @@ export class Client {
|
|
|
145
146
|
/**
|
|
146
147
|
* Underlying WebSocket instance, READONLY.
|
|
147
148
|
*/
|
|
148
|
-
get webSocket(): IStompSocket {
|
|
149
|
-
return this._stompHandler
|
|
149
|
+
get webSocket(): IStompSocket | undefined {
|
|
150
|
+
return this._stompHandler?._webSocket;
|
|
150
151
|
}
|
|
151
152
|
|
|
152
153
|
/**
|
|
@@ -298,16 +299,16 @@ export class Client {
|
|
|
298
299
|
* In case of incoming heartbeat failure, this experimental flag instructs the library
|
|
299
300
|
* to discard the socket immediately (even before it is actually closed).
|
|
300
301
|
*/
|
|
301
|
-
public discardWebsocketOnCommFailure: boolean;
|
|
302
|
+
public discardWebsocketOnCommFailure: boolean = false;
|
|
302
303
|
|
|
303
304
|
/**
|
|
304
305
|
* version of STOMP protocol negotiated with the server, READONLY
|
|
305
306
|
*/
|
|
306
|
-
get connectedVersion(): string {
|
|
307
|
+
get connectedVersion(): string | undefined {
|
|
307
308
|
return this._stompHandler ? this._stompHandler.connectedVersion : undefined;
|
|
308
309
|
}
|
|
309
310
|
|
|
310
|
-
private _stompHandler: StompHandler;
|
|
311
|
+
private _stompHandler: StompHandler | undefined;
|
|
311
312
|
|
|
312
313
|
/**
|
|
313
314
|
* if the client is active (connected or going to reconnect)
|
|
@@ -328,9 +329,6 @@ export class Client {
|
|
|
328
329
|
this.onChangeState(state);
|
|
329
330
|
}
|
|
330
331
|
|
|
331
|
-
// This will mark deactivate to complete, to be called after Websocket is closed
|
|
332
|
-
private _resolveSocketClose: (value?: PromiseLike<void> | void) => void;
|
|
333
|
-
|
|
334
332
|
/**
|
|
335
333
|
* Activation state.
|
|
336
334
|
*
|
|
@@ -481,14 +479,13 @@ export class Client {
|
|
|
481
479
|
|
|
482
480
|
if (this.state === ActivationState.DEACTIVATING) {
|
|
483
481
|
// Mark deactivation complete
|
|
484
|
-
this._resolveSocketClose();
|
|
485
|
-
this._resolveSocketClose = undefined;
|
|
486
482
|
this._changeState(ActivationState.INACTIVE);
|
|
487
483
|
}
|
|
488
484
|
|
|
489
|
-
this.onWebSocketClose(evt);
|
|
490
485
|
// The callback is called before attempting to reconnect, this would allow the client
|
|
491
486
|
// to be `deactivated` in the callback.
|
|
487
|
+
this.onWebSocketClose(evt);
|
|
488
|
+
|
|
492
489
|
if (this.active) {
|
|
493
490
|
this._schedule_reconnect();
|
|
494
491
|
}
|
|
@@ -515,11 +512,13 @@ export class Client {
|
|
|
515
512
|
|
|
516
513
|
if (this.webSocketFactory) {
|
|
517
514
|
webSocket = this.webSocketFactory();
|
|
518
|
-
} else {
|
|
515
|
+
} else if (this.brokerURL) {
|
|
519
516
|
webSocket = new WebSocket(
|
|
520
517
|
this.brokerURL,
|
|
521
518
|
this.stompVersions.protocolVersions()
|
|
522
519
|
);
|
|
520
|
+
} else {
|
|
521
|
+
throw new Error('Either brokerURL or webSocketFactory must be provided');
|
|
523
522
|
}
|
|
524
523
|
webSocket.binaryType = 'arraybuffer';
|
|
525
524
|
return webSocket;
|
|
@@ -537,20 +536,33 @@ export class Client {
|
|
|
537
536
|
|
|
538
537
|
/**
|
|
539
538
|
* Disconnect if connected and stop auto reconnect loop.
|
|
540
|
-
* Appropriate callbacks will be invoked if underlying STOMP connection
|
|
539
|
+
* Appropriate callbacks will be invoked if there is an underlying STOMP connection.
|
|
540
|
+
*
|
|
541
|
+
* This call is async. It will resolve immediately if there is no underlying active websocket,
|
|
542
|
+
* otherwise, it will resolve after the underlying websocket is properly disposed of.
|
|
543
|
+
*
|
|
544
|
+
* It is not an error to invoke this method more than once.
|
|
545
|
+
* Each of those would resolve on completion of deactivation.
|
|
541
546
|
*
|
|
542
|
-
*
|
|
543
|
-
* otherwise, it will resolve after underlying websocket is properly disposed.
|
|
547
|
+
* To reactivate, you can call [Client#activate]{@link Client#activate}.
|
|
544
548
|
*
|
|
545
|
-
*
|
|
549
|
+
* Experimental: pass `force: true` to immediately discard the underlying connection.
|
|
550
|
+
* This mode will skip both the STOMP and the Websocket shutdown sequences.
|
|
551
|
+
* In some cases, browsers take a long time in the Websocket shutdown if the underlying connection had gone stale.
|
|
552
|
+
* Using this mode can speed up.
|
|
553
|
+
* When this mode is used, the actual Websocket may linger for a while
|
|
554
|
+
* and the broker may not realize that the connection is no longer in use.
|
|
555
|
+
*
|
|
556
|
+
* It is possible to invoke this method initially without the `force` option
|
|
557
|
+
* and subsequently, say after a wait, with the `force` option.
|
|
546
558
|
*/
|
|
547
|
-
public async deactivate(): Promise<void> {
|
|
559
|
+
public async deactivate(options: { force?: boolean } = {}): Promise<void> {
|
|
560
|
+
const force: boolean = options.force || false;
|
|
561
|
+
const needToDispose = this.active;
|
|
548
562
|
let retPromise: Promise<void>;
|
|
549
563
|
|
|
550
|
-
if (this.state
|
|
551
|
-
this.debug(
|
|
552
|
-
`Already ${ActivationState[this.state]}, ignoring call to deactivate`
|
|
553
|
-
);
|
|
564
|
+
if (this.state === ActivationState.INACTIVE) {
|
|
565
|
+
this.debug(`Already INACTIVE, nothing more to do`);
|
|
554
566
|
return Promise.resolve();
|
|
555
567
|
}
|
|
556
568
|
|
|
@@ -559,15 +571,22 @@ export class Client {
|
|
|
559
571
|
// Clear if a reconnection was scheduled
|
|
560
572
|
if (this._reconnector) {
|
|
561
573
|
clearTimeout(this._reconnector);
|
|
574
|
+
this._reconnector = undefined;
|
|
562
575
|
}
|
|
563
576
|
|
|
564
577
|
if (
|
|
565
578
|
this._stompHandler &&
|
|
579
|
+
// @ts-ignore - if there is a _stompHandler, there is the webSocket
|
|
566
580
|
this.webSocket.readyState !== StompSocketState.CLOSED
|
|
567
581
|
) {
|
|
568
|
-
|
|
582
|
+
const origOnWebSocketClose = this._stompHandler.onWebSocketClose;
|
|
583
|
+
// we need to wait for the underlying websocket to close
|
|
569
584
|
retPromise = new Promise<void>((resolve, reject) => {
|
|
570
|
-
|
|
585
|
+
// @ts-ignore - there is a _stompHandler
|
|
586
|
+
this._stompHandler.onWebSocketClose = evt => {
|
|
587
|
+
origOnWebSocketClose(evt);
|
|
588
|
+
resolve();
|
|
589
|
+
};
|
|
571
590
|
});
|
|
572
591
|
} else {
|
|
573
592
|
// indicate that auto reconnect loop should terminate
|
|
@@ -575,7 +594,11 @@ export class Client {
|
|
|
575
594
|
return Promise.resolve();
|
|
576
595
|
}
|
|
577
596
|
|
|
578
|
-
|
|
597
|
+
if (force) {
|
|
598
|
+
this._stompHandler?.discardWebsocket();
|
|
599
|
+
} else if (needToDispose) {
|
|
600
|
+
this._disposeStompHandler();
|
|
601
|
+
}
|
|
579
602
|
|
|
580
603
|
return retPromise;
|
|
581
604
|
}
|
|
@@ -596,7 +619,6 @@ export class Client {
|
|
|
596
619
|
// Dispose STOMP Handler
|
|
597
620
|
if (this._stompHandler) {
|
|
598
621
|
this._stompHandler.dispose();
|
|
599
|
-
this._stompHandler = null;
|
|
600
622
|
}
|
|
601
623
|
}
|
|
602
624
|
|
|
@@ -637,9 +659,17 @@ export class Client {
|
|
|
637
659
|
* ```
|
|
638
660
|
*/
|
|
639
661
|
public publish(params: IPublishParams) {
|
|
662
|
+
this._checkConnection();
|
|
663
|
+
// @ts-ignore - we already checked that there is a _stompHandler, and it is connected
|
|
640
664
|
this._stompHandler.publish(params);
|
|
641
665
|
}
|
|
642
666
|
|
|
667
|
+
private _checkConnection() {
|
|
668
|
+
if (!this.connected) {
|
|
669
|
+
throw new TypeError('There is no underlying STOMP connection');
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
643
673
|
/**
|
|
644
674
|
* STOMP brokers may carry out operation asynchronously and allow requesting for acknowledgement.
|
|
645
675
|
* To request an acknowledgement, a `receipt` header needs to be sent with the actual request.
|
|
@@ -676,6 +706,8 @@ export class Client {
|
|
|
676
706
|
* ```
|
|
677
707
|
*/
|
|
678
708
|
public watchForReceipt(receiptId: string, callback: frameCallbackType): void {
|
|
709
|
+
this._checkConnection();
|
|
710
|
+
// @ts-ignore - we already checked that there is a _stompHandler, and it is connected
|
|
679
711
|
this._stompHandler.watchForReceipt(receiptId, callback);
|
|
680
712
|
}
|
|
681
713
|
|
|
@@ -708,6 +740,8 @@ export class Client {
|
|
|
708
740
|
callback: messageCallbackType,
|
|
709
741
|
headers: StompHeaders = {}
|
|
710
742
|
): StompSubscription {
|
|
743
|
+
this._checkConnection();
|
|
744
|
+
// @ts-ignore - we already checked that there is a _stompHandler, and it is connected
|
|
711
745
|
return this._stompHandler.subscribe(destination, callback, headers);
|
|
712
746
|
}
|
|
713
747
|
|
|
@@ -724,6 +758,8 @@ export class Client {
|
|
|
724
758
|
* See: http://stomp.github.com/stomp-specification-1.2.html#UNSUBSCRIBE UNSUBSCRIBE Frame
|
|
725
759
|
*/
|
|
726
760
|
public unsubscribe(id: string, headers: StompHeaders = {}): void {
|
|
761
|
+
this._checkConnection();
|
|
762
|
+
// @ts-ignore - we already checked that there is a _stompHandler, and it is connected
|
|
727
763
|
this._stompHandler.unsubscribe(id, headers);
|
|
728
764
|
}
|
|
729
765
|
|
|
@@ -734,6 +770,8 @@ export class Client {
|
|
|
734
770
|
* `transactionId` is optional, if not passed the library will generate it internally.
|
|
735
771
|
*/
|
|
736
772
|
public begin(transactionId?: string): ITransaction {
|
|
773
|
+
this._checkConnection();
|
|
774
|
+
// @ts-ignore - we already checked that there is a _stompHandler, and it is connected
|
|
737
775
|
return this._stompHandler.begin(transactionId);
|
|
738
776
|
}
|
|
739
777
|
|
|
@@ -750,6 +788,8 @@ export class Client {
|
|
|
750
788
|
* ```
|
|
751
789
|
*/
|
|
752
790
|
public commit(transactionId: string): void {
|
|
791
|
+
this._checkConnection();
|
|
792
|
+
// @ts-ignore - we already checked that there is a _stompHandler, and it is connected
|
|
753
793
|
this._stompHandler.commit(transactionId);
|
|
754
794
|
}
|
|
755
795
|
|
|
@@ -765,6 +805,8 @@ export class Client {
|
|
|
765
805
|
* ```
|
|
766
806
|
*/
|
|
767
807
|
public abort(transactionId: string): void {
|
|
808
|
+
this._checkConnection();
|
|
809
|
+
// @ts-ignore - we already checked that there is a _stompHandler, and it is connected
|
|
768
810
|
this._stompHandler.abort(transactionId);
|
|
769
811
|
}
|
|
770
812
|
|
|
@@ -786,6 +828,8 @@ export class Client {
|
|
|
786
828
|
subscriptionId: string,
|
|
787
829
|
headers: StompHeaders = {}
|
|
788
830
|
): void {
|
|
831
|
+
this._checkConnection();
|
|
832
|
+
// @ts-ignore - we already checked that there is a _stompHandler, and it is connected
|
|
789
833
|
this._stompHandler.ack(messageId, subscriptionId, headers);
|
|
790
834
|
}
|
|
791
835
|
|
|
@@ -807,6 +851,8 @@ export class Client {
|
|
|
807
851
|
subscriptionId: string,
|
|
808
852
|
headers: StompHeaders = {}
|
|
809
853
|
): void {
|
|
854
|
+
this._checkConnection();
|
|
855
|
+
// @ts-ignore - we already checked that there is a _stompHandler, and it is connected
|
|
810
856
|
this._stompHandler.nack(messageId, subscriptionId, headers);
|
|
811
857
|
}
|
|
812
858
|
}
|
package/src/frame-impl.ts
CHANGED
|
@@ -31,9 +31,9 @@ export class FrameImpl implements IFrame {
|
|
|
31
31
|
if (!this._body && this.isBinaryBody) {
|
|
32
32
|
this._body = new TextDecoder().decode(this._binaryBody);
|
|
33
33
|
}
|
|
34
|
-
return this._body;
|
|
34
|
+
return this._body || '';
|
|
35
35
|
}
|
|
36
|
-
private _body: string;
|
|
36
|
+
private _body: string | undefined;
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* body as Uint8Array
|
|
@@ -42,9 +42,10 @@ export class FrameImpl implements IFrame {
|
|
|
42
42
|
if (!this._binaryBody && !this.isBinaryBody) {
|
|
43
43
|
this._binaryBody = new TextEncoder().encode(this._body);
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
// At this stage it will definitely have a valid value
|
|
46
|
+
return this._binaryBody as Uint8Array;
|
|
46
47
|
}
|
|
47
|
-
private _binaryBody: Uint8Array;
|
|
48
|
+
private _binaryBody: Uint8Array | undefined;
|
|
48
49
|
|
|
49
50
|
private escapeHeaderValues: boolean;
|
|
50
51
|
private skipContentLengthHeader: boolean;
|
|
@@ -115,7 +116,7 @@ export class FrameImpl implements IFrame {
|
|
|
115
116
|
}
|
|
116
117
|
|
|
117
118
|
return new FrameImpl({
|
|
118
|
-
command: rawFrame.command,
|
|
119
|
+
command: rawFrame.command as string,
|
|
119
120
|
headers,
|
|
120
121
|
binaryBody: rawFrame.binaryBody,
|
|
121
122
|
escapeHeaderValues,
|
|
@@ -140,7 +141,10 @@ export class FrameImpl implements IFrame {
|
|
|
140
141
|
const cmdAndHeaders = this.serializeCmdAndHeaders();
|
|
141
142
|
|
|
142
143
|
if (this.isBinaryBody) {
|
|
143
|
-
return FrameImpl.toUnit8Array(
|
|
144
|
+
return FrameImpl.toUnit8Array(
|
|
145
|
+
cmdAndHeaders,
|
|
146
|
+
this._binaryBody as Uint8Array
|
|
147
|
+
).buffer;
|
|
144
148
|
} else {
|
|
145
149
|
return cmdAndHeaders + this._body + BYTE.NULL;
|
|
146
150
|
}
|
package/src/parser.ts
CHANGED
|
@@ -63,12 +63,14 @@ export class Parser {
|
|
|
63
63
|
private readonly _encoder = new TextEncoder();
|
|
64
64
|
private readonly _decoder = new TextDecoder();
|
|
65
65
|
|
|
66
|
+
// @ts-ignore - it always has a value
|
|
66
67
|
private _results: IRawFrameType;
|
|
67
68
|
|
|
68
69
|
private _token: number[] = [];
|
|
69
|
-
private _headerKey: string;
|
|
70
|
-
private _bodyBytesRemaining: number;
|
|
70
|
+
private _headerKey: string | undefined;
|
|
71
|
+
private _bodyBytesRemaining: number | undefined;
|
|
71
72
|
|
|
73
|
+
// @ts-ignore - it always has a value
|
|
72
74
|
private _onByte: (byte: number) => void;
|
|
73
75
|
|
|
74
76
|
public constructor(
|
|
@@ -176,7 +178,10 @@ export class Parser {
|
|
|
176
178
|
return;
|
|
177
179
|
}
|
|
178
180
|
if (byte === LF) {
|
|
179
|
-
this._results.headers.push([
|
|
181
|
+
this._results.headers.push([
|
|
182
|
+
this._headerKey as string,
|
|
183
|
+
this._consumeTokenAsUTF8(),
|
|
184
|
+
]);
|
|
180
185
|
this._headerKey = undefined;
|
|
181
186
|
this._onByte = this._collectHeaders;
|
|
182
187
|
return;
|
|
@@ -209,7 +214,7 @@ export class Parser {
|
|
|
209
214
|
|
|
210
215
|
private _collectBodyFixedSize(byte: number): void {
|
|
211
216
|
// It is post decrement, so that we discard the trailing NULL octet
|
|
212
|
-
if (this._bodyBytesRemaining-- === 0) {
|
|
217
|
+
if ((this._bodyBytesRemaining as number)-- === 0) {
|
|
213
218
|
this._retrievedBody();
|
|
214
219
|
return;
|
|
215
220
|
}
|
|
@@ -219,7 +224,14 @@ export class Parser {
|
|
|
219
224
|
private _retrievedBody() {
|
|
220
225
|
this._results.binaryBody = this._consumeTokenAsRaw();
|
|
221
226
|
|
|
222
|
-
|
|
227
|
+
try {
|
|
228
|
+
this.onFrame(this._results);
|
|
229
|
+
} catch (e) {
|
|
230
|
+
console.log(
|
|
231
|
+
`Ignoring an exception thrown by a frame handler. Original exception: `,
|
|
232
|
+
e
|
|
233
|
+
);
|
|
234
|
+
}
|
|
223
235
|
|
|
224
236
|
this._initState();
|
|
225
237
|
}
|
package/src/stomp-handler.ts
CHANGED
|
@@ -4,7 +4,6 @@ import { FrameImpl } from './frame-impl';
|
|
|
4
4
|
import { IMessage } from './i-message';
|
|
5
5
|
import { ITransaction } from './i-transaction';
|
|
6
6
|
import { Parser } from './parser';
|
|
7
|
-
import { StompConfig } from './stomp-config';
|
|
8
7
|
import { StompHeaders } from './stomp-headers';
|
|
9
8
|
import { StompSubscription } from './stomp-subscription';
|
|
10
9
|
import {
|
|
@@ -14,6 +13,7 @@ import {
|
|
|
14
13
|
IPublishParams,
|
|
15
14
|
IStompSocket,
|
|
16
15
|
IStompSocketMessageEvent,
|
|
16
|
+
IStomptHandlerConfig,
|
|
17
17
|
messageCallbackType,
|
|
18
18
|
StompSocketState,
|
|
19
19
|
wsErrorCallbackType,
|
|
@@ -69,16 +69,16 @@ export class StompHandler {
|
|
|
69
69
|
|
|
70
70
|
public discardWebsocketOnCommFailure: boolean;
|
|
71
71
|
|
|
72
|
-
get connectedVersion(): string {
|
|
72
|
+
get connectedVersion(): string | undefined {
|
|
73
73
|
return this._connectedVersion;
|
|
74
74
|
}
|
|
75
|
-
private _connectedVersion: string;
|
|
75
|
+
private _connectedVersion: string | undefined;
|
|
76
76
|
|
|
77
77
|
get connected(): boolean {
|
|
78
78
|
return this._connected;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
private _connected: boolean;
|
|
81
|
+
private _connected: boolean = false;
|
|
82
82
|
|
|
83
83
|
private readonly _subscriptions: { [key: string]: messageCallbackType };
|
|
84
84
|
private readonly _receiptWatchers: { [key: string]: frameCallbackType };
|
|
@@ -89,12 +89,10 @@ export class StompHandler {
|
|
|
89
89
|
private _ponger: any;
|
|
90
90
|
private _lastServerActivityTS: number;
|
|
91
91
|
|
|
92
|
-
private _onclose: (closeEvent: any) => void;
|
|
93
|
-
|
|
94
92
|
constructor(
|
|
95
93
|
private _client: Client,
|
|
96
94
|
public _webSocket: IStompSocket,
|
|
97
|
-
config:
|
|
95
|
+
config: IStomptHandlerConfig
|
|
98
96
|
) {
|
|
99
97
|
// used to index subscribers
|
|
100
98
|
this._counter = 0;
|
|
@@ -111,12 +109,26 @@ export class StompHandler {
|
|
|
111
109
|
|
|
112
110
|
this._lastServerActivityTS = Date.now();
|
|
113
111
|
|
|
114
|
-
this.
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
112
|
+
this.debug = config.debug;
|
|
113
|
+
this.stompVersions = config.stompVersions;
|
|
114
|
+
this.connectHeaders = config.connectHeaders;
|
|
115
|
+
this.disconnectHeaders = config.disconnectHeaders;
|
|
116
|
+
this.heartbeatIncoming = config.heartbeatIncoming;
|
|
117
|
+
this.heartbeatOutgoing = config.heartbeatOutgoing;
|
|
118
|
+
this.splitLargeFrames = config.splitLargeFrames;
|
|
119
|
+
this.maxWebSocketChunkSize = config.maxWebSocketChunkSize;
|
|
120
|
+
this.forceBinaryWSFrames = config.forceBinaryWSFrames;
|
|
121
|
+
this.logRawCommunication = config.logRawCommunication;
|
|
122
|
+
this.appendMissingNULLonIncoming = config.appendMissingNULLonIncoming;
|
|
123
|
+
this.discardWebsocketOnCommFailure = config.discardWebsocketOnCommFailure;
|
|
124
|
+
this.onConnect = config.onConnect;
|
|
125
|
+
this.onDisconnect = config.onDisconnect;
|
|
126
|
+
this.onStompError = config.onStompError;
|
|
127
|
+
this.onWebSocketClose = config.onWebSocketClose;
|
|
128
|
+
this.onWebSocketError = config.onWebSocketError;
|
|
129
|
+
this.onUnhandledMessage = config.onUnhandledMessage;
|
|
130
|
+
this.onUnhandledReceipt = config.onUnhandledReceipt;
|
|
131
|
+
this.onUnhandledFrame = config.onUnhandledFrame;
|
|
120
132
|
}
|
|
121
133
|
|
|
122
134
|
public start(): void {
|
|
@@ -155,17 +167,18 @@ export class StompHandler {
|
|
|
155
167
|
this.debug(`<<< ${rawChunkAsString}`);
|
|
156
168
|
}
|
|
157
169
|
|
|
158
|
-
parser.parseChunk(
|
|
170
|
+
parser.parseChunk(
|
|
171
|
+
evt.data as string | ArrayBuffer,
|
|
172
|
+
this.appendMissingNULLonIncoming
|
|
173
|
+
);
|
|
159
174
|
};
|
|
160
175
|
|
|
161
|
-
this.
|
|
176
|
+
this._webSocket.onclose = (closeEvent): void => {
|
|
162
177
|
this.debug(`Connection closed to ${this._client.brokerURL}`);
|
|
163
178
|
this._cleanUp();
|
|
164
179
|
this.onWebSocketClose(closeEvent);
|
|
165
180
|
};
|
|
166
181
|
|
|
167
|
-
this._webSocket.onclose = this._onclose;
|
|
168
|
-
|
|
169
182
|
this._webSocket.onerror = (errorEvent): void => {
|
|
170
183
|
this.onWebSocketError(errorEvent);
|
|
171
184
|
};
|
|
@@ -303,7 +316,7 @@ export class StompHandler {
|
|
|
303
316
|
this.debug(
|
|
304
317
|
'Discarding websocket, the underlying socket may linger for a while'
|
|
305
318
|
);
|
|
306
|
-
this.
|
|
319
|
+
this.discardWebsocket();
|
|
307
320
|
} else {
|
|
308
321
|
this.debug('Issuing close on the websocket');
|
|
309
322
|
this._closeWebsocket();
|
|
@@ -326,11 +339,12 @@ export class StompHandler {
|
|
|
326
339
|
this._webSocket.close();
|
|
327
340
|
}
|
|
328
341
|
|
|
329
|
-
|
|
330
|
-
if (
|
|
342
|
+
public discardWebsocket() {
|
|
343
|
+
if (typeof this._webSocket.terminate !== 'function') {
|
|
331
344
|
augmentWebsocket(this._webSocket, (msg: string) => this.debug(msg));
|
|
332
345
|
}
|
|
333
346
|
|
|
347
|
+
// @ts-ignore - this method will be there at this stage
|
|
334
348
|
this._webSocket.terminate();
|
|
335
349
|
}
|
|
336
350
|
|
|
@@ -413,9 +427,11 @@ export class StompHandler {
|
|
|
413
427
|
|
|
414
428
|
if (this._pinger) {
|
|
415
429
|
clearInterval(this._pinger);
|
|
430
|
+
this._pinger = undefined;
|
|
416
431
|
}
|
|
417
432
|
if (this._ponger) {
|
|
418
433
|
clearInterval(this._ponger);
|
|
434
|
+
this._ponger = undefined;
|
|
419
435
|
}
|
|
420
436
|
}
|
|
421
437
|
|
|
@@ -5,14 +5,14 @@ import { StompHeaders } from './stomp-headers';
|
|
|
5
5
|
*
|
|
6
6
|
* Part of `@stomp/stompjs`.
|
|
7
7
|
*/
|
|
8
|
-
export
|
|
8
|
+
export interface StompSubscription {
|
|
9
9
|
/**
|
|
10
10
|
* Id associated with this subscription.
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
id: string;
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Unsubscribe. See [Client#unsubscribe]{@link Client#unsubscribe} for an example.
|
|
16
16
|
*/
|
|
17
|
-
|
|
17
|
+
unsubscribe: (headers?: StompHeaders) => void;
|
|
18
18
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { IFrame } from './i-frame';
|
|
2
2
|
import { IMessage } from './i-message';
|
|
3
3
|
import { StompHeaders } from './stomp-headers';
|
|
4
|
+
import { Versions } from './versions';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* This callback will receive a `string` as parameter.
|
|
@@ -91,9 +92,9 @@ export type RawHeaderType = [string, string];
|
|
|
91
92
|
* @internal
|
|
92
93
|
*/
|
|
93
94
|
export interface IRawFrameType {
|
|
94
|
-
command: string;
|
|
95
|
+
command: string | undefined;
|
|
95
96
|
headers: RawHeaderType[];
|
|
96
|
-
binaryBody: Uint8Array;
|
|
97
|
+
binaryBody: Uint8Array | undefined;
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
/**
|
|
@@ -154,3 +155,29 @@ export enum ActivationState {
|
|
|
154
155
|
DEACTIVATING,
|
|
155
156
|
INACTIVE,
|
|
156
157
|
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
162
|
+
export interface IStomptHandlerConfig {
|
|
163
|
+
debug: debugFnType;
|
|
164
|
+
stompVersions: Versions;
|
|
165
|
+
connectHeaders: StompHeaders;
|
|
166
|
+
disconnectHeaders: StompHeaders;
|
|
167
|
+
heartbeatIncoming: number;
|
|
168
|
+
heartbeatOutgoing: number;
|
|
169
|
+
splitLargeFrames: boolean;
|
|
170
|
+
maxWebSocketChunkSize: number;
|
|
171
|
+
forceBinaryWSFrames: boolean;
|
|
172
|
+
logRawCommunication: boolean;
|
|
173
|
+
appendMissingNULLonIncoming: boolean;
|
|
174
|
+
discardWebsocketOnCommFailure: boolean;
|
|
175
|
+
onConnect: frameCallbackType;
|
|
176
|
+
onDisconnect: frameCallbackType;
|
|
177
|
+
onStompError: frameCallbackType;
|
|
178
|
+
onWebSocketClose: closeEventCallbackType;
|
|
179
|
+
onWebSocketError: wsErrorCallbackType;
|
|
180
|
+
onUnhandledMessage: messageCallbackType;
|
|
181
|
+
onUnhandledReceipt: frameCallbackType;
|
|
182
|
+
onUnhandledFrame: frameCallbackType;
|
|
183
|
+
}
|