快速解決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-next-admin項(xiàng)目使用cdn加速詳細(xì)配置
這篇文章主要為大家介紹了vue-next-admin項(xiàng)目使用cdn加速的詳細(xì)配置,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
Vue不能watch數(shù)組和對(duì)象變化解決方案
這篇文章主要為大家介紹了Vue不能watch數(shù)組和對(duì)象變化解決方案示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
詳解Vue全局組件的掛載之實(shí)現(xiàn)彈窗組件
這篇文章主要為大家詳細(xì)介紹了如何通過Vue全局組件的掛載來實(shí)現(xiàn)彈窗組件,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的可以了解一下2022-11-11
vue使用vuedraggable對(duì)列表進(jìn)行拖拽排序
vuedraggable 是一個(gè)基于 Vue 的拖拽排序組件,它可以讓你輕松地在 Vue 應(yīng)用中實(shí)現(xiàn)拖拽排序功能,下面就跟隨小編一起來了解下它的具體應(yīng)用吧2024-12-12
Vue 讀取HTMLCollection列表的length為0問題
這篇文章主要介紹了Vue 讀取HTMLCollection列表的length為0問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
vue使用rem實(shí)現(xiàn) 移動(dòng)端屏幕適配
這篇文章主要介紹了vue使用rem實(shí)現(xiàn) 移動(dòng)端屏幕適配的相關(guān)知識(shí),通過實(shí)例代碼介紹了vue用rem布局的實(shí)現(xiàn)代碼,需要的朋友可以參考下2018-09-09

