Java实现websocket时,每次发送的文本长度默认限制在8k范围内,原因是
org.apache.tomcat.websocket.WsSession进行了设置
// Buffers
static final int DEFAULT_BUFFER_SIZE = Integer.getInteger(
"org.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE", 8 * 1024)
.intValue();
private volatile int maxBinaryMessageBufferSize = Constants.DEFAULT_BUFFER_SIZE;
private volatile int maxTextMessageBufferSize = Constants.DEFAULT_BUFFER_SIZE;
如果发送超过8k的消息,就会报错:
No async message support and buffer too small Buffer size: [8,192], Message size: [10,240]
那么要实现类似发送文件的base64,网上有两种方式实现,第一种是实现ServletContextInitializer接口,对onStartup进行重载,大体代码如下:
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
import org.springframework.web.util.WebAppRootListener;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
/**
* 设置websocket 传输内容的字节大小。 默认8k 当前设置50M
*/
@EnableWebSocket
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class WebSocketConfig implements ServletContextInitializer {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.addListener(WebAppRootListener.class);
servletContext.setInitParameter("org.apache.tomcat.websocket.textBufferSize","52428800");
servletContext.setInitParameter("org.apache.tomcat.websocket.binaryBufferSize","52428800");
}
}
这个方法会出现问题就是,每个websocket会话初始化就会占用设置的内存,如上代码是50M,这样连接达到一定数量就会内存溢出。
我们通常会使用另外一种方式,就是在注解
@OnMessage设置消息大小,代码如下:
@OnMessage(maxMessageSize=5242880)
public void onMessage(String message, Session session, @PathParam("deviceNo")String deviceNo) {
log.info("message:"+message +" ;deviceNo"+deviceNo);
try {
JSONObject obj = JSONObject.parseObject(message);
String funid = (String)obj.get("funid");
JSONObject contentObj = (JSONObject)obj.get("content");
}
} catch (Exception e) {
e.printStackTrace();
}
}
第二种方式在500个连接情况下经过测试不会造成内存溢出