快速解决spring的websocket作为客户端接收数据时1009错误(非ServletServerContainer问题)

 更新时间:2025年09月26日 14:26:55   作者:嚯呀怪怪怪  
Spring Boot WebSocket客户端因缓冲区过小导致连接断开(错误1009),正确解决方案是通过WebSocketContainer自定义缓冲区大小和过期时间,而非配置类,需在创建StandardWebSocketClient时传入预设的container实例

项目场景

使用springboot自带的websocket库作为客户端向设备进行连接获取设备推送的数据,包括纯数据以及携带base64图片的数据

问题描述

WebSocket接收数据时连接断开

报错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缓冲区过小,装不下数据

需要给websocket缓冲区扩容,但是问题就在于全网查询后,包括StackOverflow及ChatGPT的回答都聚焦于两个点

  • 一个是修改tomocat的缓冲区,在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();
        // 在此处设置bufferSize
        container.setMaxTextMessageBufferSize(512000);
        container.setMaxBinaryMessageBufferSize(512000);
        container.setMaxSessionIdleTimeout(15 * 60000L);
        return container;
    }
}

问题也就在这里

这个配置文件并不能解决实际的缓冲区大小,但确实是对的思路。

解决方案

首先我们查看连接所使用的类的源码

正常通过StandardWebSocketClient client = new StandardWebSocketClient();进行创建一个连接的client,使用默认的配置。但是StandardWebSocketClient是可以构造一个container传入的

public StandardWebSocketClient(WebSocketContainer webSocketContainer) {
    Assert.notNull(webSocketContainer, "WebSocketContainer must not be null");
    this.webSocketContainer = webSocketContainer;
}

继续查看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();
}

问题的关键就在这里!set方法告诉我们WebSocketContainer 是可以设置缓冲区大小的

因此解决方案就出来了

在新建客户端连接的时候,构造好container传入就可以自定义缓冲区大小和过期时间了,代码如下

WebSocketContainer container = new WsWebSocketContainer();
// 设置二进制消息缓冲区大小(以字节为单位)
container.setDefaultMaxBinaryMessageBufferSize(5120000);
// 设置文本消息缓冲区大小(以字节为单位)
container.setDefaultMaxTextMessageBufferSize(5120000);
// 设置会话空闲超时时间(以毫秒为单位)
container.setDefaultMaxSessionIdleTimeout(15 * 60000L);
StandardWebSocketClient client = new StandardWebSocketClient(container);

大功告成!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Vue中引用JSON数据的方法小结

    Vue中引用JSON数据的方法小结

    在现代Web开发中,JSON是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成,Vue.js作为一个流行的前端框架,支持多种方式引入和处理JSON数据,本文将详细介绍几种在Vue中引用JSON数据的方法,需要的朋友可以参考下
    2024-10-10
  • Vue实现快捷键录入功能的示例代码

    Vue实现快捷键录入功能的示例代码

    有的时候项目需要在页面使用快捷键,而且需要对快捷键进行维护。本文将为大家展示Vue实现快捷键录入功能的示例代码,感兴趣的可以了解一下
    2022-04-04
  • vue 实现移动端键盘搜索事件监听

    vue 实现移动端键盘搜索事件监听

    今天小编就为大家分享一篇vue 实现移动端键盘搜索事件监听,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • Vue源码makeMap函数深入分析

    Vue源码makeMap函数深入分析

    vue源码中的makeMap用在很多地方,主要是判断标签是原生标签还是用户自定义的组件,但是标签很多,如果每判断一次都执行一次循环,累计下来,性能损耗还是很大的,makeMap就是解决这个问题出现的
    2022-08-08
  • vue实现图片上传到后台

    vue实现图片上传到后台

    这篇文章主要为大家详细介绍了vue实现图片上传到后台,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • Vue中父子组件的值传递与方法传递

    Vue中父子组件的值传递与方法传递

    这篇文章主要介绍了Vue中父子组件的值传递与方法传递,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • vue 弹出遮罩层样式实例

    vue 弹出遮罩层样式实例

    这篇文章主要介绍了vue 弹出遮罩层样式实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • Vue 3 响应式系统中ref 在 reactive 中的自动解包行为解析

    Vue 3 响应式系统中ref 在 reactive 中的自动解包行为

    Vue3中,ref与reactive配合使用时会自动解包,使代码更简洁,响应式系统更智能,替换ref会断开旧连接,浅层reactive/shallowRef不触发解包,但是需注意区分,下面通过示例给大家介绍Vue3响应式探秘:ref 在reactive中的自动解包行为解析,感兴趣的朋友一起看看吧
    2025-07-07
  • Vue如何拖动滑块

    Vue如何拖动滑块

    这篇文章主要介绍了Vue如何拖动滑块问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • 详细对比Ember.js和Vue.js

    详细对比Ember.js和Vue.js

    这篇文章主要介绍了详细对比Ember.js和Vue.js,对JS框架感兴趣的同学,可以参考下
    2021-05-05

最新评论