I am using Spring-Websockets 4.2 with SockJS.
Since the messages received by clients can be quite large, I would like to use partial messages. My subclass of TextWebSocketHandler does override supportsPartialMessages to return true. However, since the SockJsWebSocketHandler that is created by Spring does not support partial messages, I still get an error code=1009, reason=The decoded text message was too big for the output buffer and the endpoint does not support partial messages
.
As a workaround, I've increased the buffer size to 1 MB as described here, but since I have to support quite a large number of clients (~2000 at the same time), this requires way too much memory.
Is there any way to use partial messages with SockJS?
In my case, my tomcat server work with TextWebSocketHandler
.
Before doing this, you need to check this, supportsPartialMessages.
First of all, override supportsPartialMessages()
as below.
//This value set as true in my properties file. Just for test. actually you don't need this.
@Value("#{config['server.supportsPartialMessages']}")
private boolean supportsPartialMessages;
//If you need to handle partial message, should return true.
@Override
public boolean supportsPartialMessages() {
return supportsPartialMessages;
}
And then I add "messageRoom" attribute to store partial message to each websocket session when connection is established.
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
super.afterConnectionEstablished(session);
//I think this is easier to keep each message and each client.
session.getAttributes().put("messageRoom", new StringBuilder(session.getTextMessageSizeLimit()));
}
When you get message from client, do this.
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
super.handleTextMessage(session, message);
StringBuilder sbTemp = (StringBuilder)session.getAttributes().get("messageRoom");
//isLast() will tell you this is last chunk or not.
if(message.isLast() == false) {
sbTemp.append(Payload);
}else {
if(sbTemp.length() != 0) {
sbTemp.append(Payload);
this.logger.info(session.getRemoteAddress() + ":RECEIVE_TO[CLIENT][PARTIAL][" + sbTemp.length() + "]:" + sbTemp.toString());
doYourWork(session, sbTemp.toString());
//Release memory would be nice.
sbTemp.setLength(0);
sbTemp.trimToSize();
}else {
this.logger.info(session.getRemoteAddress() + ":RECEIVE_TO[CLIENT][WHOLE]:" + message.getPayload());
doYourWork(session, Payload);
}
}
}
This is done a few years ago, so I can't remember where I got this. But I still appreciate to them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With