stomp-js / rx-stomp

STOMP adaptor for RxJS
Apache License 2.0
111 stars 21 forks source link

splitLargeFrames with Spring fails with slow networks #472

Closed Joe-EdgeTech closed 1 year ago

Joe-EdgeTech commented 1 year ago

Our project which uses Spring and splitLargeFrames:true will fail with critical websocket errors if the network is slow. You can even recreate the bug by turning the Chrome developer console to simulate Slow 3G networks. Sending a large amount of data that triggers the split of a frame causes it.

A few of the errors we'll see when this occurs:

WebSocket connection to 'ws://localhost:9090/ws/906/znivmp4x/websocket' failed: One or more reserved bits are on: reserved1 = 1, reserved2 = 1, reserved3 = 1

WebSocket connection to 'ws://localhost:9090/ws/958/ibo3ls5v/websocket' failed: A server must not mask any frames that it sends to the client.

I'm hoping that there is a splitLargeFrames test case somewhere that you can run with the network throttled by the browser to confirm what we're seeing.

With our product you can unthrottle the browser and the application runs perfectly every single time. As soon as you throttle it, the websocket crashes.

Here is our config:


export const CLIENT_ID = UIDService.getID();

export const myRxStompConfig: RxStompConfig = {
  // Headers
  // Typical keys: login, passcode, host
  connectHeaders: {
    clientId: CLIENT_ID
  },

  webSocketFactory: () => {
    return new SockJS( window.location.origin + '/ws');
  },
  // How often to heartbeat?
  // Interval in milliseconds, set to 0 to disable
  heartbeatIncoming: 0, // Typical value 0 - disabled
  heartbeatOutgoing: 25000, // Typical value 20000 - every 20 seconds

  // Wait in milliseconds before attempting auto reconnect
  // Set to 0 to disable
  // Typical value 500 (500 milli seconds)
  reconnectDelay: 1000,

  // This enables non-standard message splitting, which is apparently only used by spring websocket brokers (which we use)
  splitLargeFrames: true
};```
kum-deepak commented 1 year ago

With caution, I do not use and have very little idea of Spring.

Currently, there is no test case to cover the splitLargeFrames feature. Unless contributed by any person, it is not planned for the near future either.

The split large frames feature is not part of the protocol and is only supported by Spring. This is a poorly conceived design and has inherent flaws. The splitLargeFrames mechanism will fail if there is a packet drop. The Websocket standard has an alternate mechanism that is transparent, i.e., without additional configuration (probably not supported by Spring).

Chrome's throttle mode eats away Websocket frames, which, probably is incorrect behavior. Throttling should drop packets at the lower (IP) level and not at the Websocket level.

With all the above, my suggestion - Stomp (or most of the messaging systems) is not suitable for large data. If at all it needs to transfer large data, the split and join should be handled by the application layer.

Another suggestion - avoid using the SockJs compatibility layer. You are likely to get better reliability if you used Websockets directly (Spring supports this).

kum-deepak commented 1 year ago

If you need any further assistance, please enable debug and attach the entire console output.