首先说明一下我出现这个错误是出现在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
先给出解决方法,然后再描述解决流程
-
减少websocket一次传输的内容
-
由于没找到可配置项,只能修改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 boot
2.1.6.RELEASE
的版本中搭建了websocket的demo测试这个问题仍然存在,在修改了源码后,将最大值改为1024000,可以正常传输。在2.1.6.RELEASE
版本中aggregateFrames
的值由构造器中传入
由于websocket中的内容可以实现分段传输,最终还是使用了方案一。参考 https://blog.csdn.net/xiunai78/article/details/85159611
issue:https://github.com/spring-cloud/spring-cloud-gateway/issues/623