快速解決spring的websocket作為客戶端接收數(shù)據(jù)時(shí)1009錯(cuò)誤(非ServletServerContainer問題)
項(xiàng)目場景
使用springboot自帶的websocket庫作為客戶端向設(shè)備進(jìn)行連接獲取設(shè)備推送的數(shù)據(jù),包括純數(shù)據(jù)以及攜帶base64圖片的數(shù)據(jù)
問題描述
WebSocket接收數(shù)據(jù)時(shí)連接斷開
報(bào)錯(cuò)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ū)擴(kuò)容,但是問題就在于全網(wǎng)查詢后,包括StackOverflow及ChatGPT的回答都聚焦于兩個(gè)點(diǎn)
- 一個(gè)是修改tomocat的緩沖區(qū),在jar包啟動(dòng)時(shí)加上如下啟動(dòng)命令
-Dorg.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE=327680
- 一個(gè)是寫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;
}
}
問題也就在這里
這個(gè)配置文件并不能解決實(shí)際的緩沖區(qū)大小,但確實(shí)是對(duì)的思路。
解決方案
首先我們查看連接所使用的類的源碼
正常通過StandardWebSocketClient client = new StandardWebSocketClient();進(jìn)行創(chuàng)建一個(gè)連接的client,使用默認(rèn)的配置。但是StandardWebSocketClient是可以構(gòu)造一個(gè)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ū)大小的
因此解決方案就出來了
在新建客戶端連接的時(shí)候,構(gòu)造好container傳入就可以自定義緩沖區(qū)大小和過期時(shí)間了,代碼如下
WebSocketContainer container = new WsWebSocketContainer(); // 設(shè)置二進(jìn)制消息緩沖區(qū)大小(以字節(jié)為單位) container.setDefaultMaxBinaryMessageBufferSize(5120000); // 設(shè)置文本消息緩沖區(qū)大?。ㄒ宰止?jié)為單位) container.setDefaultMaxTextMessageBufferSize(5120000); // 設(shè)置會(huì)話空閑超時(shí)時(shí)間(以毫秒為單位) container.setDefaultMaxSessionIdleTimeout(15 * 60000L); StandardWebSocketClient client = new StandardWebSocketClient(container);
大功告成!
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue中引用JSON數(shù)據(jù)的方法小結(jié)
在現(xiàn)代Web開發(fā)中,JSON是一種輕量級(jí)的數(shù)據(jù)交換格式,易于人閱讀和編寫,同時(shí)也易于機(jī)器解析和生成,Vue.js作為一個(gè)流行的前端框架,支持多種方式引入和處理JSON數(shù)據(jù),本文將詳細(xì)介紹幾種在Vue中引用JSON數(shù)據(jù)的方法,需要的朋友可以參考下2024-10-10
vue 實(shí)現(xiàn)移動(dòng)端鍵盤搜索事件監(jiān)聽
今天小編就為大家分享一篇vue 實(shí)現(xiàn)移動(dòng)端鍵盤搜索事件監(jiān)聽,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-11-11
Vue 3 響應(yīng)式系統(tǒng)中ref 在 reactive 中的自動(dòng)解包行為
Vue3中,ref與reactive配合使用時(shí)會(huì)自動(dòng)解包,使代碼更簡潔,響應(yīng)式系統(tǒng)更智能,替換ref會(huì)斷開舊連接,淺層reactive/shallowRef不觸發(fā)解包,但是需注意區(qū)分,下面通過示例給大家介紹Vue3響應(yīng)式探秘:ref 在reactive中的自動(dòng)解包行為解析,感興趣的朋友一起看看吧2025-07-07

