20
20
import java .net .URI ;
21
21
import java .nio .ByteBuffer ;
22
22
import java .time .Duration ;
23
+ import java .util .ArrayList ;
23
24
import java .util .Collections ;
24
25
import java .util .List ;
25
26
import java .util .concurrent .CompletableFuture ;
@@ -75,16 +76,13 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif
75
76
76
77
private static final Log logger = LogFactory .getLog (WebSocketStompClient .class );
77
78
78
- /**
79
- * The default max size for in&outbound STOMP message.
80
- */
81
- private static final int DEFAULT_MESSAGE_MAX_SIZE = 64 * 1024 ;
82
79
83
80
private final WebSocketClient webSocketClient ;
84
81
85
- private int inboundMessageSizeLimit = DEFAULT_MESSAGE_MAX_SIZE ;
82
+ private int inboundMessageSizeLimit = 64 * 1024 ;
86
83
87
- private int outboundMessageSizeLimit = DEFAULT_MESSAGE_MAX_SIZE ;
84
+ @ Nullable
85
+ private Integer outboundMessageSizeLimit ;
88
86
89
87
private boolean autoStartup = true ;
90
88
@@ -131,7 +129,7 @@ public void setTaskScheduler(@Nullable TaskScheduler taskScheduler) {
131
129
* Since a STOMP message can be received in multiple WebSocket messages,
132
130
* buffering may be required and this property determines the maximum buffer
133
131
* size per message.
134
- * <p>By default this is set to 64 * 1024 (64K), see {@link WebSocketStompClient#DEFAULT_MESSAGE_MAX_SIZE} .
132
+ * <p>By default this is set to 64 * 1024 (64K).
135
133
*/
136
134
public void setInboundMessageSizeLimit (int inboundMessageSizeLimit ) {
137
135
this .inboundMessageSizeLimit = inboundMessageSizeLimit ;
@@ -148,18 +146,19 @@ public int getInboundMessageSizeLimit() {
148
146
* Configure the maximum size allowed for outbound STOMP message.
149
147
* If STOMP message's size exceeds {@link WebSocketStompClient#outboundMessageSizeLimit},
150
148
* STOMP message is split into multiple frames.
151
- * <p>By default this is set to 64 * 1024 (64K), see {@link WebSocketStompClient#DEFAULT_MESSAGE_MAX_SIZE} .
149
+ * <p>By default this is not set in which case each STOMP message are not split .
152
150
* @since 6.2
153
151
*/
154
- public void setOutboundMessageSizeLimit (int outboundMessageSizeLimit ) {
152
+ public void setOutboundMessageSizeLimit (Integer outboundMessageSizeLimit ) {
155
153
this .outboundMessageSizeLimit = outboundMessageSizeLimit ;
156
154
}
157
155
158
156
/**
159
157
* Get the configured outbound message buffer size in bytes.
160
158
* @since 6.2
161
159
*/
162
- public int getOutboundMessageSizeLimit () {
160
+ @ Nullable
161
+ public Integer getOutboundMessageSizeLimit () {
163
162
return this .outboundMessageSizeLimit ;
164
163
}
165
164
@@ -479,8 +478,13 @@ public CompletableFuture<Void> sendAsync(Message<byte[]> message) {
479
478
try {
480
479
WebSocketSession session = this .session ;
481
480
Assert .state (session != null , "No WebSocketSession available" );
482
- for (WebSocketMessage <?> webSocketMessage : this .codec .encode (message , session .getClass ())) {
483
- session .sendMessage (webSocketMessage );
481
+ if (this .codec .hasSplittingEncoder ()) {
482
+ for (WebSocketMessage <?> outMessage : this .codec .encodeAndSplit (message , session .getClass ())) {
483
+ session .sendMessage (outMessage );
484
+ }
485
+ }
486
+ else {
487
+ session .sendMessage (this .codec .encode (message , session .getClass ()));
484
488
}
485
489
future .complete (null );
486
490
}
@@ -592,11 +596,13 @@ private static class StompWebSocketMessageCodec {
592
596
593
597
private final BufferingStompDecoder bufferingDecoder ;
594
598
599
+ @ Nullable
595
600
private final SplittingStompEncoder splittingEncoder ;
596
601
597
- public StompWebSocketMessageCodec (int inboundMessageSizeLimit , int outboundMessageSizeLimit ) {
602
+ public StompWebSocketMessageCodec (int inboundMessageSizeLimit , @ Nullable Integer outboundMessageSizeLimit ) {
598
603
this .bufferingDecoder = new BufferingStompDecoder (DECODER , inboundMessageSizeLimit );
599
- this .splittingEncoder = new SplittingStompEncoder (ENCODER , outboundMessageSizeLimit );
604
+ this .splittingEncoder = (outboundMessageSizeLimit != null ?
605
+ new SplittingStompEncoder (ENCODER , outboundMessageSizeLimit ) : null );
600
606
}
601
607
602
608
public List <Message <byte []>> decode (WebSocketMessage <?> webSocketMessage ) {
@@ -622,21 +628,41 @@ else if (webSocketMessage instanceof BinaryMessage binaryMessage) {
622
628
return result ;
623
629
}
624
630
625
- public List <WebSocketMessage <?>> encode (Message <byte []> message , Class <? extends WebSocketSession > sessionType ) {
631
+ public boolean hasSplittingEncoder () {
632
+ return (this .splittingEncoder != null );
633
+ }
634
+
635
+ public WebSocketMessage <?> encode (Message <byte []> message , Class <? extends WebSocketSession > sessionType ) {
636
+ StompHeaderAccessor accessor = getStompHeaderAccessor (message );
637
+ byte [] payload = message .getPayload ();
638
+ byte [] frame = ENCODER .encode (accessor .getMessageHeaders (), payload );
639
+ return (useBinary (accessor , payload , sessionType ) ? new BinaryMessage (frame ) : new TextMessage (frame ));
640
+ }
641
+
642
+ public List <WebSocketMessage <?>> encodeAndSplit (Message <byte []> message , Class <? extends WebSocketSession > sessionType ) {
643
+ Assert .state (this .splittingEncoder != null , "No SplittingEncoder" );
644
+ StompHeaderAccessor accessor = getStompHeaderAccessor (message );
645
+ byte [] payload = message .getPayload ();
646
+ List <byte []> frames = this .splittingEncoder .encode (accessor .getMessageHeaders (), payload );
647
+ boolean useBinary = useBinary (accessor , payload , sessionType );
648
+
649
+ List <WebSocketMessage <?>> messages = new ArrayList <>(frames .size ());
650
+ frames .forEach (frame -> messages .add (useBinary ? new BinaryMessage (frame ) : new TextMessage (frame )));
651
+ return messages ;
652
+ }
653
+
654
+ private static StompHeaderAccessor getStompHeaderAccessor (Message <byte []> message ) {
626
655
StompHeaderAccessor accessor = MessageHeaderAccessor .getAccessor (message , StompHeaderAccessor .class );
627
656
Assert .notNull (accessor , "No StompHeaderAccessor available" );
628
- byte [] payload = message .getPayload ();
629
- List <byte []> frames = splittingEncoder .encode (accessor .getMessageHeaders (), payload );
657
+ return accessor ;
658
+ }
659
+
660
+ private static boolean useBinary (
661
+ StompHeaderAccessor accessor , byte [] payload , Class <? extends WebSocketSession > sessionType ) {
630
662
631
- boolean useBinary = (payload .length > 0 &&
663
+ return (payload .length > 0 &&
632
664
!(SockJsSession .class .isAssignableFrom (sessionType )) &&
633
665
MimeTypeUtils .APPLICATION_OCTET_STREAM .isCompatibleWith (accessor .getContentType ()));
634
-
635
- List <WebSocketMessage <?>> messages = new ArrayList <>();
636
- for (byte [] frame : frames ) {
637
- messages .add (useBinary ? new BinaryMessage (frame ) : new TextMessage (frame ));
638
- }
639
- return messages ;
640
666
}
641
667
}
642
668
0 commit comments