首先说明一下我出现这个错误是出现在websocket的服务端,由于websocket向前端传输的内容过大,超过了65536 bytes。这个问题是由于Gateway的原因。
Gateway中的错误为

 ERROR o.s.b.a.w.r.error.DefaultErrorWebExceptionHandler - Failed to handle request [GET http://localhost:10003/websocketDeploy/flowSocket]  
io.netty.handler.codec.TooLongFrameException: content length exceeded 65536 bytes.
	at io.netty.handler.codec.MessageAggregator.handleOversizedMessage(MessageAggregator.java:399)
	...
	at java.lang.Thread.run(Thread.java:748)
ERROR o.s.web.server.adapter.HttpWebHandlerAdapter - Failed to handle request [GET http://localhost:10003/websocketDeploy/flowSocket]  
java.lang.IllegalStateException: Status and headers already sent

Gateway的版本为2.0.3.RELEASE

先给出解决方法,然后再描述解决流程

  1. 减少websocket一次传输的内容

  2. 由于没找到可配置项,只能修改gateway中的源码,将传输内容改大一点

    针对方案二,需要修改的是org.springframework.web.reactive.socket.adapter.ReactorNettyWebSocketSession类的receive方法,通过查看源码可以看到DEFAULT_FRAME_MAX_SIZE的65536

    @Override
    public Flux<WebSocketMessage> receive() {
        return getDelegate().getInbound()
            .aggregateFrames(DEFAULT_FRAME_MAX_SIZE)
            .receiveFrames()
            .map(super::toMessage);
    }
    

    使用Jclasslib等工具可以直接修改class文件,然后将源class文件覆盖

    具体使用方式可以参考这里

    说一下我自己的解决方案,在spring boot2.1.6.RELEASE的版本中搭建了websocket的demo测试这个问题仍然存在,在修改了源码后,将最大值改为1024000,可以正常传输。在2.1.6.RELEASE版本中aggregateFrames的值由构造器中传入

    由于websocket中的内容可以实现分段传输,最终还是使用了方案一。

    参考 https://blog.csdn.net/xiunai78/article/details/85159611
    issuehttps://github.com/spring-cloud/spring-cloud-gateway/issues/623

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐