Changing the implementation of server.websocket.javax.WebSocketEndPoint

7 views
Skip to first unread message

Marek Gregor

unread,
Oct 19, 2022, 7:57:01 AM10/19/22
to cometd-dev

Class org.cometd.server.websocket.javax.WebSocketEndPoint implements Servlet API interface MessageHandler.Whole<String>.

This interface directs Apache Tomcat to use the pre-allocated text buffer for the whole message.

From Tomcat documentation:

"If the application does not define a MessageHandler.Partial for incoming text messages, any incoming text messages must be buffered so the entire message can be delivered in a single call to the registered MessageHandler.Whole for text messages."

The default size of this buffer used in Tomcat is 8Kb, and it could be changed by the Servlet API method: javax.websocket.server.WebSocketContainer.setDefaultMaxTextMessageBufferSize(). Alternatively, it could be changed by the web init parameter (ws.maxMessageSize) of CometDServlet. But CometD implementation under the hood only calls this Servlet API method.

Now the problem is when my CometD browser client needs from time to time to send or receive a bigger message (e.g., 20Mb). So I tried to change ws.maxMessageSize web init parameter, and it works perfectly. But the side-effect of this change is that Tomcat now allocates 20 Mb buffer per every WebSocket session, no matter if the allocated memory is used or not. This has tremendous consequences for per-user memory requirements.

The solution is to implement MessageHandler.Partial<String> interface instead of MessageHandler.Whole<String> for org.cometd.server.websocket.javax.WebSocketEndPoint class. As described in Tomcat documentation noted above: with MessageHandler.Partial implementation Tomcat doesn't use the pre-allocated buffer. CometDServlet web init parameter ws.maxMessageSize should also be changed, setting WebSocketContainer.setDefaultMaxTextMessage should be removed, and check for max message size should be manually implemented in WebSocketEndPoint class.


Please note reasoning for this change is exclusively due to specific WebSocket implementation in Apache Tomcat. I have not found any pre-allocated buffer in the Jetty server/client code - only checks for message size are present. Unfortunately, this issue is also a case for javax/jakarta WebSocket client implementation in Tomcat (java CometD client). Still, here I can switch to the Jetty implementation of the CometD client.


Question to the admired maintainer of CometD library Simone Bordet: Does it make sense for you to change this in mainstream CometD versions (6/7)

PS: I have implemented the change for my project; I could share code or create a pull request and help with it ...

thanks

Marek Gregor







Simone Bordet

unread,
Oct 19, 2022, 12:31:15 PM10/19/22
to comet...@googlegroups.com
Hi,
I'm not sure what change you refer to?
Like you write above, this seems to be a Tomcat issue, so I don't see
anything that CometD should do?

--
Simone Bordet
----
http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.
Reply all
Reply to author
Forward
0 new messages