【问题标题】:How to increase output buffer for spring sockjs websocket server implementation如何增加spring sockjs websocket服务器实现的输出缓冲区
【发布时间】:2014-03-10 22:24:54
【问题描述】:

我使用了 sockjs websocket 服务器的 spring 实现,无法传输超过 8KB 的消息,以下是错误

2014-02-12 19:36:29,990 - org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession - DEBUG - SockJS session id=35n41xel was closed, CloseStatus [code=1009, reason=The decoded text message was too big for the output buffer and the endpoint does not support partial messages]

知道如何增加缓冲区大小


我使用了以下工厂,因为 spring sockjs 利用了 tomcat 容器(应用程序部署在 tomcat 中,我还进行了调试以确认它确实使用了 tomcat lib)

@Bean
public WebSocketContainerFactoryBean createWebSocketContainer() {
    WebSocketContainerFactoryBean container = new WebSocketContainerFactoryBean();
    container.setMaxTextMessageBufferSize(16384);
    container.setMaxBinaryMessageBufferSize(8192);
    return container;
}

然后我的 URL 映射看起来

@Override 
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(coBrowseSockJsCustomerHandler(), "/sockjs/cobrowse/customer/").withSockJS();}

我需要在某个地方用 sockjs 设置这个 bean 吗? sockjs 怎么知道它必须使用这个工厂?

【问题讨论】:

    标签: spring websocket sockjs spring-websocket


    【解决方案1】:

    在我的 web.xml 文件中设置这个对我有用:

    <context-param>
      <param-name>org.apache.tomcat.websocket.textBufferSize</param-name>
      <param-value>65536</param-value>
    </context-param>
    <context-param>
      <param-name>org.apache.tomcat.websocket.binaryBufferSize</param-name>
      <param-value>65536</param-value>
    </context-param>
    

    【讨论】:

      【解决方案2】:

      对于客户端:

      @Bean
      public static WebSocketStompClient getClient() {
          List<Transport> transports = new ArrayList<>();
          WebSocketContainer container = ContainerProvider.getWebSocketContainer();
          container.setDefaultMaxBinaryMessageBufferSize(1024 * 1024);
          container.setDefaultMaxTextMessageBufferSize(1024 * 1024);
          transports.add(new WebSocketTransport(new StandardWebSocketClient(container)));
          WebSocketClient webSocketClient = new SockJsClient(transports);
          WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient);
          stompClient.setInboundMessageSizeLimit(Integer.MAX_VALUE);
          stompClient.setMessageConverter(new MappingJackson2MessageConverter());
          return stompClient;
      }
      

      服务器端:

      @Bean
      public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() {
          ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
          container.setMaxTextMessageBufferSize(32768);
          container.setMaxBinaryMessageBufferSize(32768);
          logger.info("Websocket factory returned");
          return container;
      }
      

      【讨论】:

      • 如果我不使用 Spring 怎么办?
      • @Albert Hendriks,我不知道。标记为与春季相关的问题
      • @AlbertHendriks WebSocketContainer container = ContainerProvider.getWebSocketContainer(); container.setDefaultMaxBinaryMessageBufferSize(1024 * 1024);不特定于 Spring,因此对于非 Spring 应用程序也是如此
      • 我花了几天时间才发现我在客户端代码中的错误,希望它可以为别人节省一天的时间:你可以在 spring 文档中找到几乎相同的 sn-p 代码,除了三行代码是关于 Websocket 容器的,所以我复制了这三行并将它们插入到 spring 的 sn-p 之前。但我错过了下一行,它有一个重要的变化,并使用new StandardWebSocketClient(container) 中的容器作为参数。结果,容器在 StandardWebsocketClient 的空构造函数中使用消息大小的默认值再次初始化。
      【解决方案3】:

      使用来自http://docs.spring.io/spring/docs/4.0.1.RELEASE/javadoc-api/index.html?org/springframework/web/socket/sockjs/SockJsService.html 的线索解决了它 - 获取了 ServletServerContainerFactoryBean 并设置了属性,这很有效

      @Bean
      public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() {
          ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
          container.setMaxTextMessageBufferSize(32768);
          container.setMaxBinaryMessageBufferSize(32768);
          logger.info("Websocket factory returned");
          return container;
      }
      

      【讨论】:

      • 你指定的数字是bit、byte还是kb??
      • 这在我将文件从客户端传递到服务器时有效,但如果我将文件从服务器发送到客户端则无效
      • 更高的数字对我有用。我选择了 99999999。有人可以告诉我使用更大的数字是否有任何缺点?
      • @KaranGujral,它会占用你的记忆。
      【解决方案4】:

      您可以configure the websocket engine 并增加缓冲区大小。

      请注意,根据您要使用的实际大小,请记住这些消息将完全缓冲在内存中! 如果您的客户支持,您可以考虑使用partial messages

      【讨论】:

      • 我用它来配置引擎 - 在我的例子中 spring sockjs 使用的是 tomcat 引擎,但它没有工作
      • Brian,你能帮我看看如何设置容器属性吗?就我而言,它是tomcat。我看了tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html 作为如何增加缓冲区大小并按照建议尝试设置 servlet 上下文初始化参数.. 但它没有用!是否有任何拦截器或配置可用于实现此目的?
      • 这在我将文件从客户端传递到服务器时有效,但如果我将文件从服务器发送到客户端则无效
      猜你喜欢
      • 2015-02-16
      • 2016-07-20
      • 2021-02-25
      • 1970-01-01
      • 2016-02-08
      • 1970-01-01
      • 2013-05-04
      • 2014-03-10
      相关资源
      最近更新 更多