如何增加Spring SockJS WebSocket服务器实现的输出缓冲区

13

我使用了Spring实现的sockjs WebSocket服务器,但无法传输超过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库)

@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();}

我需要在哪里设置这个bean才能使用sockjs?sockjs如何知道它必须使用这个工厂?

5个回答

18
用从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;
}

1
你所指定的数字是以位、字节还是千字节为单位? - BiJ
如果我从客户端传送文件到服务器,这个可以用。但是如果我从服务器发送文件到客户端,则无法使用。 - gstackoverflow
一个更高的数字对我有用。我选择了99999999。请问是否有使用更大数字的任何缺点? - Karan Gujral
1
@KaranGujral,它将会占用你的内存。 - gbenroscience

13

对于客户端:

@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
1
@Albert Hendriks,我不知道。问题标记为与Spring相关。 - gstackoverflow
@AlbertHendriks WebSocketContainer container = ContainerProvider.getWebSocketContainer(); container.setDefaultMaxBinaryMessageBufferSize(1024 * 1024); 不仅适用于Spring,对于非Spring应用程序也是一样的。 - Adelin
我花了好几天的时间才找到我客户端代码中的错误,希望能为其他人节省时间:你可以在Spring文档中找到几乎相同的代码片段,除了三行关于Websocket容器的代码外,所以我复制了这三行并将它们插入到Spring的代码片段之前。但是我错过了下一行,这一行有一个重要的更改,并将容器作为参数在new StandardWebSocketClient(container)中使用。结果,在StandardWebsocketClient的空构造函数中再次初始化容器,并使用默认值设置消息大小。 - Sunchezz

1

在启动Spring应用程序之前,您可以设置属性。

System.setProperty("org.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE", (1024*1024).toString()).

我尝试了多种不起作用的bean配置,但当我查看代码时,似乎在多个地方都读取了此属性。我相信有些bean配置会起作用,但如果您不想尝试许多不同的配置直到找到一个有效的配置,您可以只设置此参数。


1
你可以配置websocket引擎并增加缓冲区大小。
注意,根据实际需要使用的大小,记住这些消息将完全缓存在内存中!如果客户端支持,您可能希望考虑使用部分消息

我用它来配置引擎 - 在我的情况下,Spring SockJS使用Tomcat引擎,但它没有工作。 - cpandey05
Brian,你能帮我设置容器属性吗?在我的情况下是Tomcat。我查看了http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html以了解如何增加缓冲区大小,并尝试设置Servlet上下文初始化参数,但它没有起作用!是否有任何拦截器或配置可用于实现此目的? - cpandey05
如果我从客户端传递文件到服务器,这个方法可以工作,但是如果我从服务器发送文件到客户端,它就不起作用了。 - gstackoverflow

0

在我的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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接