How to increase output buffer for spring sockjs websocket server implementation
Asked Answered
M

5

13

I have used spring implementation of sockjs websocket server and unable to transmit message over 8KB, following is the error

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]

Any Idea how can I increase the buffer size


I used following factory as spring sockjs leverages tomcat container (App is deployed in tomcat and I also debugged to confirm that it indeed uses tomcat lib)

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

And then my URL mapping looks

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

Do I need to set this bean with sockjs somewhere? how does sockjs knows that it has to use this facory?

Macmacabre answered 12/2, 2014 at 14:20 Comment(0)
M
18

Solved it by using clue from http://docs.spring.io/spring/docs/4.0.1.RELEASE/javadoc-api/index.html?org/springframework/web/socket/sockjs/SockJsService.html -got hold of ServletServerContainerFactoryBean and set the properties, this worked

@Bean
public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() {
    ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
    container.setMaxTextMessageBufferSize(32768);
    container.setMaxBinaryMessageBufferSize(32768);
    logger.info("Websocket factory returned");
    return container;
}
Macmacabre answered 17/2, 2014 at 7:15 Comment(4)
The number you are specifying are in bit, byte or kb??Dartboard
This works if I pass file from client to server but doesn't if I senf file from server to clientMoonscape
A higher number worked for me. I went with 99999999. Can someone please tell me if there are any drawbacks of using a bigger number ?Xerarch
@KaranGujral, its going to hog your memory.Toponym
M
13

for client side:

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

for server side:

@Bean
public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() {
    ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
    container.setMaxTextMessageBufferSize(32768);
    container.setMaxBinaryMessageBufferSize(32768);
    logger.info("Websocket factory returned");
    return container;
}
Moonscape answered 10/7, 2017 at 16:23 Comment(4)
What if I'm not using Spring?Selfmade
@Albert Hendriks, I don't know. Question tagged as spring relatedMoonscape
@AlbertHendriks WebSocketContainer container = ContainerProvider.getWebSocketContainer(); container.setDefaultMaxBinaryMessageBufferSize(1024 * 1024); is not specific to Spring so it is the same for non-spring appsThorsten
It took me days to find MY mistake in clientside code and hopefully it saves someone others day: You can find nearly the same snippet of code in the spring docs, except the three lines of code which are about the Websocket container, so i copied these three lines and inserted them before the snippet from spring. but i missed the next line, which has an important change and uses the container in new StandardWebSocketClient(container) as a paramater. As a result, the container gets initialized again in the empty constructor of StandardWebsocketClient with default values for message sizes.Mairamaire
G
1

You can configure the websocket engine and increase the buffer size.

Watch out, depending on the actual size you'd like to use, remember that those messages will be buffered entirely in memory! You may want to consider using partial messages if your client supports it.

Gretel answered 16/2, 2014 at 9:4 Comment(3)
I used that to configure the engine -In my case spring sockjs is using tomcat engine, but it did not workMacmacabre
Brian, Can you help me as how to set the container properties? In my case it's tomcat. I took a look at tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html as how to increase the buffer size and as suggested tried setting the servlet context initialization parameter .. But it did not work! Is there any interceptor or configuration which can be used to achieve this?Macmacabre
This works if I pass file from client to server but doesn't if I senf file from server to clientMoonscape
B
1

Before you start the spring app you can set the property

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

I've tried multiple bean configurations that didn't work but this property seems to be read in multiple places when I looked at the code. I'm sure there is some bean configuration that would have worked but if you don't want to bother trying many different ones until one works you can just set this parameter.

Briton answered 9/1, 2023 at 19:23 Comment(0)
K
0

Setting this in my web.xml file worked for me:

<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>
Krigsman answered 24/6, 2021 at 17:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.