从 Tomcat 9 到客户端的 Websocket 二进制消息拆分为 2 个或更多 tcp 数据包
Posted
技术标签:
【中文标题】从 Tomcat 9 到客户端的 Websocket 二进制消息拆分为 2 个或更多 tcp 数据包【英文标题】:Websocket Binary message from Tomcat 9 to client splitted to 2 or more tcp packets 【发布时间】:2016-08-26 11:01:52 【问题描述】:我正在使用 Tomcat 9 和 Spring。
我的网络应用程序有一个 websocket 服务。
我的应用程序使用sendMessage
向客户端发送二进制消息:
org.springframework.web.socket.WebSocketSession.
我收集了wireshark的tcp数据包。我看到每个二进制 websocket 消息至少使用 2 个 TCP 数据包。
第一个数据包是标头,它很小。
似乎Java代码总是先发送头然后再发送数据。
如何解决此问题? 是 Spring 还是 Tomcat 的问题?
【问题讨论】:
我创建的 - 这是 Tomcat 的问题。 【参考方案1】:根本问题是tomcat 实现中的一个错误。他们的 websocket 消息的 send 方法获取要发送的消息块列表,并通过它们对每个缓冲区调用 send() 和 flush() 进行迭代。当它们在单独的缓冲区中对标头进行编码时,标头和正文将因此以您正确识别的不同数据报的形式写入线路。我调查了这个问题,发现你试图向他们提交一个补丁,但由于额外的内存分配而被他们拒绝。
我向他们提出了另一个解决方案,他们只需在写入所有块后调用一次 flush(),而不是在每个块之间调用一次。这会导致消息的所有部分在可能的情况下进入单个数据报,而无需添加任何额外的内存分配。我在我的项目中测试了修复并验证了它,并且 tomcat 已经在他们的下一个版本中采用了它。
该修复将包含在 8.5.X 和 9.0 中。您必须升级 tomcat 才能解决此问题。
我在 tomcat 的 github 中提供了该问题的链接以供参考。
https://github.com/apache/tomcat85/commit/47c211eb3ee7f9be2df6c313fb65351feabd42d1
【讨论】:
以上是关于从 Tomcat 9 到客户端的 Websocket 二进制消息拆分为 2 个或更多 tcp 数据包的主要内容,如果未能解决你的问题,请参考以下文章
Tomcat架构解析-----CoyoteHTTPAJPHTTP2等协议