如何解决Java WebSocketStompClient的MessageTooLargeException异常
解决WebSocketStompClient的MessageTooLargeException问题
你遇到的org.eclipse.jetty.websocket.api.MessageTooLargeException是Jetty WebSocket客户端传输层的大小限制导致的,仅调用stompClient.setInboundMessageSizeLimit()不会生效——因为WebSocket层会先对消息大小做检查,触发异常后不会走到Stomp的处理逻辑。
正确的解决方式是同时配置Jetty底层WebSocket客户端的消息大小限制,以及Stomp客户端的帧大小限制,具体步骤和修改后的代码如下:
解决方案步骤
- 创建Jetty原生的
WebSocketClient实例,手动设置maxTextMessageSize和maxBinaryMessageSize,覆盖默认的65536字节限制 - 将配置好的Jetty客户端传入
StandardWebSocketClient,再构建WebSocketTransport - 保留
stompClient.setInboundMessageSizeLimit()设置,确保Stomp帧层面的限制与WebSocket层匹配或更大
修改后的示例代码
重点调整connect()方法中的客户端配置部分:
import org.apache.log4j.Logger; import org.springframework.messaging.simp.stomp.StompFrameHandler; import org.springframework.messaging.simp.stomp.StompHeaders; import org.springframework.messaging.simp.stomp.StompSession; import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.web.socket.WebSocketHttpHeaders; import org.springframework.web.socket.client.standard.StandardWebSocketClient; import org.springframework.web.socket.messaging.WebSocketStompClient; import org.springframework.web.socket.sockjs.client.SockJsClient; import org.springframework.web.socket.sockjs.client.Transport; import org.springframework.web.socket.sockjs.client.WebSocketTransport; import org.springframework.web.socket.sockjs.frame.Jackson2SockJsMessageCodec; import java.lang.reflect.Type; import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; public class HelloClient { private static Logger logger = Logger.getLogger(HelloClient.class); StompSession session; private final static WebSocketHttpHeaders headers = new WebSocketHttpHeaders(); public ListenableFuture<StompSession> connect() { // 配置Jetty原生WebSocket客户端,调整消息大小限制(这里设为1MB,可按需修改) org.eclipse.jetty.websocket.client.WebSocketClient jettyWebSocketClient = new org.eclipse.jetty.websocket.client.WebSocketClient(); jettyWebSocketClient.setMaxTextMessageSize(1024 * 1024); jettyWebSocketClient.setMaxBinaryMessageSize(1024 * 1024); // 将配置好的Jetty客户端传入Spring的StandardWebSocketClient Transport webSocketTransport = new WebSocketTransport(new StandardWebSocketClient(jettyWebSocketClient)); List<Transport> transports = Collections.singletonList(webSocketTransport); SockJsClient sockJsClient = new SockJsClient(transports); sockJsClient.setMessageCodec(new Jackson2SockJsMessageCodec()); WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient); // 同步设置Stomp层面的入站消息大小限制 stompClient.setInboundMessageSizeLimit(1024 * 1024); String url = "https://www.test.com"; return stompClient.connect(url, headers, new MyHandler()); } // 以下原有方法保持不变 public void subscribeMsg(StompSession stompSession) throws ExecutionException, InterruptedException { stompSession.subscribe("/topic/test", new StompFrameHandler() { public Type getPayloadType(StompHeaders stompHeaders) { return byte[].class; } public void handleFrame(StompHeaders stompHeaders, Object o) { logger.info("Received message " + new String((byte[]) o)); String response = new String((byte[]) o); } }); } private class MyHandler extends StompSessionHandlerAdapter { public void afterConnected(StompSession stompSession, StompHeaders stompHeaders) { logger.info("Now connected"); session = stompSession; } } public boolean isConnected() { try { Thread.sleep(500); return session != null && session.isConnected(); } catch (Exception e) { logger.warn("Error happens when checking connection status, ", e); return false; } } public static void main(String[] args) throws Exception { HelloClient helloClient = new HelloClient(); ListenableFuture<StompSession> f = helloClient.connect(); StompSession stompSession = f.get(); helloClient.subscribeMsg(stompSession); while (true) { if (!helloClient.isConnected()) { logger.info("wss disconnected "); logger.info("need re-create "); } } } }
配置完成后,Jetty WebSocket客户端会允许更大的消息通过,Stomp层面也能处理对应的帧大小,即可解决消息大小超限的问题。
内容的提问来源于stack exchange,提问作者Bob Lee
相关产品推荐
相关产品推荐

