websocket SpringCloud Gateway onCloseWrapper code : 1009 reason:Max frame length of 65536
·
服务主要架构 springcloud
springboot
springcloud gateway 网关
nginx 反向代理
问题:
websocket客户端和服务端正常交互,但是发现会断开连接,不知道什么原因,客户端断开提示: WebsocketBase::onCloseWrapper code : 1009 reason:Max frame length of 65536 has bean exceeded. remote:true
分析:
大致意思还是 服务端处理不了这么大的数据帧,数据超过了65536 ,和上一个问题报的不一样,上次出现的原因是客户端建立和服务器建立连接,没有配置该session能接收多大的数据,现已配置如下图

到开发环境又出现这个问题,但是上个问题改过之后,本地调试正常的啊,本地调试时直接连接该服务,比较差异,开发环境经过nginx和网关服务,那么问题一定出现在了 网关或者是nginx上面了,就先排查网关,还真是网关的问题,通过google和查看源码发现
*/
public abstract class NettyWebSocketSessionSupport<T> extends AbstractWebSocketSession<T> {
/**
* The default max size for inbound WebSocket frames.
*/
public static final int DEFAULT_FRAME_MAX_SIZE = 64 * 1024;
Netty的WebFlux中的WebSocket默认65536字节的帧,好了问题真相大白,重写此NettyWebSocketSessionSupport 类重新注入即可,但发现下面ReactorNettyRequestUpgradeStrategy 可以修改netty策略。
/**
* A {@link RequestUpgradeStrategy} for use with Reactor Netty.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class ReactorNettyRequestUpgradeStrategy implements RequestUpgradeStrategy {
private int maxFramePayloadLength = NettyWebSocketSessionSupport.DEFAULT_FRAME_MAX_SIZE;
/**
* Configure the maximum allowable frame payload length. Setting this value
* to your application's requirement may reduce denial of service attacks
* using long data frames.
* <p>Corresponds to the argument with the same name in the constructor of
* {@link io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory
* WebSocketServerHandshakerFactory} in Netty.
* <p>By default set to 65536 (64K).
* @param maxFramePayloadLength the max length for frames.
* @since 5.1
*/
public void setMaxFramePayloadLength(Integer maxFramePayloadLength) {
this.maxFramePayloadLength = maxFramePayloadLength;
}
/**
* Return the configured max length for frames.
* @since 5.1
*/
public int getMaxFramePayloadLength() {
return this.maxFramePayloadLength;
}
@Override
public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler,
@Nullable String subProtocol, Supplier<HandshakeInfo> handshakeInfoFactory) {
ServerHttpResponse response = exchange.getResponse();
HttpServerResponse reactorResponse = ((AbstractServerHttpResponse) response).getNativeResponse();
HandshakeInfo handshakeInfo = handshakeInfoFactory.get();
NettyDataBufferFactory bufferFactory = (NettyDataBufferFactory) response.bufferFactory();
return reactorResponse.sendWebsocket(subProtocol, this.maxFramePayloadLength,
(in, out) -> {
ReactorNettyWebSocketSession session =
new ReactorNettyWebSocketSession(
in, out, handshakeInfo, bufferFactory, this.maxFramePayloadLength);
return handler.handle(session);
});
}
解决方法:
@Configuration
public class WebsocketFluxGatewayConfig {
private static Integer DEFAULT_FRAME_MAX_SIZE = 100 * 1024;
@Bean
@Primary
public WebSocketService customWebSocketService() {
ReactorNettyRequestUpgradeStrategy requestUpgradeStrategy = new ReactorNettyRequestUpgradeStrategy();
requestUpgradeStrategy.setMaxFramePayloadLength(DEFAULT_FRAME_MAX_SIZE);
return new HandshakeWebSocketService(requestUpgradeStrategy);
}
}
解决!!
更多推荐
所有评论(0)