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个连接情况下经过测试不会造成内存溢出

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐