快速解决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-router定义元信息meta操作

    vue-router定义元信息meta操作

    这篇文章主要介绍了vue-router定义元信息meta操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • vue-next-admin项目使用cdn加速详细配置

    vue-next-admin项目使用cdn加速详细配置

    这篇文章主要为大家介绍了vue-next-admin项目使用cdn加速的详细配置,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • Vue不能watch数组和对象变化解决方案

    Vue不能watch数组和对象变化解决方案

    这篇文章主要为大家介绍了Vue不能watch数组和对象变化解决方案示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • 详解Vue全局组件的挂载之实现弹窗组件

    详解Vue全局组件的挂载之实现弹窗组件

    这篇文章主要为大家详细介绍了如何通过Vue全局组件的挂载来实现弹窗组件,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的可以了解一下
    2022-11-11
  • vue使用vuedraggable对列表进行拖拽排序

    vue使用vuedraggable对列表进行拖拽排序

    vuedraggable 是一个基于 Vue 的拖拽排序组件,它可以让你轻松地在 Vue 应用中实现拖拽排序功能,下面就跟随小编一起来了解下它的具体应用吧
    2024-12-12
  • Vue 读取HTMLCollection列表的length为0问题

    Vue 读取HTMLCollection列表的length为0问题

    这篇文章主要介绍了Vue 读取HTMLCollection列表的length为0问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • 关于vant折叠面板默认展开问题

    关于vant折叠面板默认展开问题

    这篇文章主要介绍了关于vant折叠面板默认展开问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • vue使用rem实现 移动端屏幕适配

    vue使用rem实现 移动端屏幕适配

    这篇文章主要介绍了vue使用rem实现 移动端屏幕适配的相关知识,通过实例代码介绍了vue用rem布局的实现代码,需要的朋友可以参考下
    2018-09-09
  • 浅谈Vue 初始化性能优化

    浅谈Vue 初始化性能优化

    本篇文章主要介绍了浅谈Vue 初始化性能优化,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Vue与Nuxt的区别及使用说明

    Vue与Nuxt的区别及使用说明

    这篇文章主要介绍了Vue与Nuxt的区别及使用说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04

最新评论