我在SockJS中使用Spring-Websockets 4.2。
由于客户端收到的消息可能很大,因此我想使用部分消息。我的TextWebSocketHandler子类确实覆盖了supportPartialMessages以返回true。但是,由于由Spring创建的SockJsWebSocketHandler不支持部分消息,因此我仍然收到错误code=1009, reason=The decoded text message was too big for the output buffer and the endpoint does not support partial messages
。
作为一种解决方法,我已经按照here的描述将缓冲区大小增加到1 MB,但是由于我必须支持大量的客户端(同时〜2000个),因此需要太多的内存。
有没有办法在SockJS中使用部分消息?
就我而言,我的tomcat服务器与TextWebSocketHandler
一起使用。在执行此操作之前,您需要检查一下supportsPartialMessages。
首先,如下覆盖supportsPartialMessages()
。
//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;
}
然后添加“ messageRoom”属性,以在建立连接时将部分消息存储到每个websocket会话。
@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())); }
当您从客户端收到消息时,请执行此操作。
@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); } } }
这是几年前完成的,所以我不记得我从哪里得到的。但我仍然感谢他们。