SpringCloud處理Websocket消息過長自動斷開連接?


最近發現Websocket發送超過6w個字節的時候就會自動斷開連接,前端控制台沒有報錯信息,Websocket后端也沒有報錯信息,這就迷了。網上一搜,方案大致兩種:消息分片和調整消息限制長度。消息分片不考慮,那么只有調整消息限制長度的方案。

1、調整tomcat容器的限制

在Websocket的配置中,定義Container的配置。

@Configuration
@EnableWebSocket
public class WebsocketConfiguration implements WebSocketConfigurer {

    private static final int MAX_MESSAGE_SIZE = 20 * 1024; 
    private static final long MAX_IDLE = 60 * 60 * 1000;

    @Bean
    public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(MAX_MESSAGE_SIZE);
        container.setMaxBinaryMessageBufferSize(MAX_MESSAGE_SIZE);
        container.setMaxSessionIdleTimeout(MAX_IDLE);
        return container;
    }
}

但是還是沒有起到作用,Websocket依然斷開。
注意:MAX_MESSAGE_SIZE不應設置過大,否則建立連接頻繁申請過大的空間容易導致內存溢出
參考:websocket影響內存泄漏的兩個點
TOMCAT websocket 多連接內存泄漏與jetty對比分析

2、調整Gateway轉發對消息長度的限制

在排查日志的時候,發現Spring Cloud Gateway報錯了,如下:

io.netty.handler.codec.CorruptedFrameException: Max frame length of 65536 has been exceeded.

這Gateway也來插一腳,大致就是推送的消息長度不能超過65536字節。
具體解決方法,上網了一下,參考https://blog.csdn.net/wu_xijie/article/details/103166605。Websocket發送消息沒有再斷開,但只解決了發送期間消息長度的問題,在Websocket建立連接的時候,發送的消息超過6w個字節照樣出錯。

3、調整netty建立時候消息長度的限制

這個和上面的解決不一樣,替換初始化的Bean比較困難,最后通過修改源碼來進行調整長度的限制。主要修改的是HttpServerWSOperations這個類的初始化時,增加WebSocketServerHandshakerFactory 的maxFramePayloadLength的參數。修改完后,重新打包,覆蓋原來項目依賴的Jar包。

4、最后

其實,如果你不是一定要Gateway來轉發Websocket的話,可以直接用nginx轉發Websocket到對應的服務,那就沒有Gateway轉發限制的煩惱了。如果不用Gateway轉發,那么只需要第一步設置就行了,第二第三步都不需要。

⚠️注意

新版本已經可以通過配置文件來修改這個值:spring.cloud.gateway.httpclient.websocket.max-frame-payload-length


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM