我使用Tomcat 9和Spring。
我的web应用程序有一个websocket服务
我的应用程序使用sendMessage
向客户端发送二进制消息:
org.springframework.web.socket.WebSocketSession.
我用wireshark收集tcp报文。我看到每个二进制websocket消息至少使用2个TCP数据包。
第一个包是报头,它很小。
Java代码似乎总是先发送头数据,然后发送其余数据。
如何修复此行为?是Spring还是Tomcat的问题?
底层问题是tomcat实现中的一个bug。他们的websocket消息发送方法获取了一个消息块列表来发送,并对每个缓冲区调用send()和flush()进行迭代。由于它们在单独的缓冲区中编码报头,因此报头和正文将以您正确识别的不同数据报的形式写入网络。我调查了这个问题,发现你曾试图向他们提交一个补丁,但由于额外的内存分配,他们拒绝了。
我建议对它们进行另一个修复,在所有块都写完之后调用flush(),而不是在每个块之间。这将导致消息的所有部分在可能的情况下放入单个数据报中,而无需添加任何额外的内存分配。我在我的项目中测试了这个修复并验证了它,tomcat已经在他们的下一个版本中采用了它。
修复将包含在8.5中。X和9.0。你必须升级tomcat来解决这个问题。
我在tomcat的github中提供了一个问题的链接供参考。
https://github.com/apache/tomcat85/commit/47c211eb3ee7f9be2df6c313fb65351feabd42d1