[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[备忘]tomcat与websocket,更改缓存大小

上一篇:[备忘]拉代码,传到新工程的git命令
下一篇:[备忘]JDKJDK1.8 编译时报错,未知的@param,@return什么的

添加日期:2023/2/8 10:22:56 快速返回   返回列表 阅读460次
tomcat的常量类:


public class Constants {

    public static final String BINARY_BUFFER_SIZE_SERVLET_CONTEXT_INIT_PARAM =
            "org.apache.tomcat.websocket.binaryBufferSize";
    public static final String TEXT_BUFFER_SIZE_SERVLET_CONTEXT_INIT_PARAM =
            "org.apache.tomcat.websocket.textBufferSize";
    public static final String ENFORCE_NO_ADD_AFTER_HANDSHAKE_CONTEXT_INIT_PARAM =
            "org.apache.tomcat.websocket.noAddAfterHandshake";

    public static final String SERVER_CONTAINER_SERVLET_CONTEXT_ATTRIBUTE =
            "javax.websocket.server.ServerContainer";
}

     
            
tomcat启动时,会new一个WsServerContainer(它是WsWebSocketContainer的子类),
然后放入ServletContext,名称就是"javax.websocket.server.ServerContainer"。
这个名字好像是java的websocket规范规定的。

(1)创建WsServerContainer实例时,会从web.xml里读取context的param,也就是常量类的前三个。
所以,最简单的设置方法就是web.xml里设置,如:
<context-param>
     <param-name>org.apache.tomcat.websocket.textBufferSize</param-name>
     <param-value>81920</param-value>
</context-param>
<context-param>
     <param-name>org.apache.tomcat.websocket.binaryBufferSize</param-name>
     <param-value>81920</param-value>
</context-param>
默认8192字节,也就是8KB


(2)第二种,是spring的ServletServerContainerFactoryBean,
它会从ServletContext中获取ServerContainer
this.serverContainer = (ServerContainer)servletContext.getAttribute("javax.websocket.server.ServerContainer");
然后给ServerContainer设置参数,如这两个BufferSize。


<bean class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean">
    <property name="maxTextMessageBufferSize" value="81920"/>
    <property name="maxBinaryMessageBufferSize" value="81920"/>
</bean>


或者注解方式


@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(81920);
        container.setMaxBinaryMessageBufferSize(81920);
        return container;
    }
}


效果跟第一种一样的,只是赋值时机不同。

(3)第三种,就是手写代码


webSocketContainer = ContainerProvider.getWebSocketContainer();
webSocketContainer.setDefaultMaxTextMessageBufferSize(81920);
webSocketContainer.setDefaultMaxBinaryMessageBufferSize(81920);


tomcat的话,getWebSocketContainer每次都new了一个WsWebSocketContainer返回的,
所以每次都要设置。

(4)注解@ServerEndpoint,就是注册入口
@ServerEndpoint(value = "/xx/yyy", configurator = SpringConfigurator.class)
public class xxxWebsocketServer{}

tomcat启动时,会扫描这个注解,然后自动注册。
用的ServerContainer就是ServletContext中那个。
这个ServerContainer是单例,全局唯一的。

(5)创建WsSession时,会从ServerContainer获取这两个Size,复制给session的俩属性。
创建buffer时,会用这俩属性来设置大小。
所以,这个size是每个session的buffer大小,不能设置得太大。session一多,就完蛋了。

(6)服务端,收到消息超过buffersize时,
服务端返回关闭websocket的消息:The decoded text message was too big for the output buffer and the endpoint does not support partial messages
客户端回复关闭websocket。
然后双向关闭socket连接。
具体代码在tomcat的WsFrameBase里。




 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved