快速解決spring的websocket作為客戶端接收數(shù)據(jù)時1009錯誤(非ServletServerContainer問題)
項目場景
使用springboot自帶的websocket庫作為客戶端向設(shè)備進行連接獲取設(shè)備推送的數(shù)據(jù),包括純數(shù)據(jù)以及攜帶base64圖片的數(shù)據(jù)
問題描述
WebSocket接收數(shù)據(jù)時連接斷開
報錯1009 The decoded text message was too big for the output buffer and the endpoint does not support partial messages
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// 處理接收到的消息
logger.info("Received message from device: " + message.getPayload());
}
原因分析
WebSocket緩沖區(qū)過小,裝不下數(shù)據(jù)
需要給websocket緩沖區(qū)擴容,但是問題就在于全網(wǎng)查詢后,包括StackOverflow及ChatGPT的回答都聚焦于兩個點
- 一個是修改tomocat的緩沖區(qū),在jar包啟動時加上如下啟動命令
-Dorg.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE=327680
- 一個是寫Config類
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
// 在此處設(shè)置bufferSize
container.setMaxTextMessageBufferSize(512000);
container.setMaxBinaryMessageBufferSize(512000);
container.setMaxSessionIdleTimeout(15 * 60000L);
return container;
}
}
問題也就在這里
這個配置文件并不能解決實際的緩沖區(qū)大小,但確實是對的思路。
解決方案
首先我們查看連接所使用的類的源碼
正常通過StandardWebSocketClient client = new StandardWebSocketClient();進行創(chuàng)建一個連接的client,使用默認的配置。但是StandardWebSocketClient是可以構(gòu)造一個container傳入的
public StandardWebSocketClient(WebSocketContainer webSocketContainer) {
Assert.notNull(webSocketContainer, "WebSocketContainer must not be null");
this.webSocketContainer = webSocketContainer;
}
繼續(xù)查看WebSocketContainer 的源碼
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package javax.websocket;
import java.io.IOException;
import java.net.URI;
import java.util.Set;
public interface WebSocketContainer {
long getDefaultAsyncSendTimeout();
void setAsyncSendTimeout(long var1);
Session connectToServer(Object var1, URI var2) throws DeploymentException, IOException;
Session connectToServer(Class<?> var1, URI var2) throws DeploymentException, IOException;
Session connectToServer(Endpoint var1, ClientEndpointConfig var2, URI var3) throws DeploymentException, IOException;
Session connectToServer(Class<? extends Endpoint> var1, ClientEndpointConfig var2, URI var3) throws DeploymentException, IOException;
long getDefaultMaxSessionIdleTimeout();
void setDefaultMaxSessionIdleTimeout(long var1);
int getDefaultMaxBinaryMessageBufferSize();
void setDefaultMaxBinaryMessageBufferSize(int var1);
int getDefaultMaxTextMessageBufferSize();
void setDefaultMaxTextMessageBufferSize(int var1);
Set<Extension> getInstalledExtensions();
}
問題的關(guān)鍵就在這里!set方法告訴我們WebSocketContainer 是可以設(shè)置緩沖區(qū)大小的
因此解決方案就出來了
在新建客戶端連接的時候,構(gòu)造好container傳入就可以自定義緩沖區(qū)大小和過期時間了,代碼如下
WebSocketContainer container = new WsWebSocketContainer(); // 設(shè)置二進制消息緩沖區(qū)大小(以字節(jié)為單位) container.setDefaultMaxBinaryMessageBufferSize(5120000); // 設(shè)置文本消息緩沖區(qū)大?。ㄒ宰止?jié)為單位) container.setDefaultMaxTextMessageBufferSize(5120000); // 設(shè)置會話空閑超時時間(以毫秒為單位) container.setDefaultMaxSessionIdleTimeout(15 * 60000L); StandardWebSocketClient client = new StandardWebSocketClient(container);
大功告成!
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue 讀取HTMLCollection列表的length為0問題
這篇文章主要介紹了Vue 讀取HTMLCollection列表的length為0問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06

