Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Websocket transport downgraded to long-polling after being disconnected for some time #20747

Open
mperktold opened this issue Dec 18, 2024 · 2 comments

Comments

@mperktold
Copy link

Description of the bug

This is related to #18398.

When connection is down for some time (about 8 min for me), eventually the websocket is closed and tries to reconnect:

vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342 Wed Dec 18 2024 18:35:24 GMT+0100 (Mitteleuropäische Normalzeit) Atmosphere: websocket.onclose
vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342  Websocket closed, reason: Connection was closed abnormally (that is, with no close frame being sent). - wasClean: false
log @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342
warn @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3348
atmosphere.AtmosphereRequest._websocket.onclose @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:1560
vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342 Wed Dec 18 2024 18:35:24 GMT+0100 (Mitteleuropäische Normalzeit) Atmosphere: Firing onClose (closed case)
FlowClient-DKebW1gN.js:8589 Push connection closed
vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342 Wed Dec 18 2024 18:35:24 GMT+0100 (Mitteleuropäische Normalzeit) Atmosphere: Request already closed, not firing onClose (closed case)
vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342 Wed Dec 18 2024 18:35:24 GMT+0100 (Mitteleuropäische Normalzeit) Atmosphere: invoking .close() on WebSocket object
vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342 Wed Dec 18 2024 18:35:24 GMT+0100 (Mitteleuropäische Normalzeit) Atmosphere: Firing onReconnect
FlowClient-DKebW1gN.js:3352 Reopening push connection
vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342 Wed Dec 18 2024 18:35:24 GMT+0100 (Mitteleuropäische Normalzeit) Atmosphere: Firing onReconnect

When this has failed for several times, long-polling is tried instead of websocket:

vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342 Websocket failed on first connection attempt. Downgrading to long-polling and resending
FlowClient-DKebW1gN.js:771  Push connection using primary method (websocket) failed. Trying with long-polling
uD @ FlowClient-DKebW1gN.js:771
kk @ FlowClient-DKebW1gN.js:1382
Tp @ FlowClient-DKebW1gN.js:8620
(anonym) @ FlowClient-DKebW1gN.js:6895
Eb2 @ FlowClient-DKebW1gN.js:1650
Hb2 @ FlowClient-DKebW1gN.js:4915
(anonym) @ FlowClient-DKebW1gN.js:2618
_reconnectWithFallbackTransport @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:1797
atmosphere.AtmosphereRequest._websocket.onclose @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:1589
vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342 Wed Dec 18 2024 18:36:34 GMT+0100 (Mitteleuropäische Normalzeit) Atmosphere: ajaxRequest.onreadystatechange, new state: 4
vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342  long-polling connection failed with status: 0 Unable to connect
log @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342
warn @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3348
ajaxRequest.onreadystatechange @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:2065
XMLHttpRequest.send
_executeRequest @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:2191
_execute @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:676
(anonym) @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:1812
setTimeout
_reconnectWithFallbackTransport @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:1810
atmosphere.AtmosphereRequest._websocket.onclose @ vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:1589
vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342 Wed Dec 18 2024 18:36:34 GMT+0100 (Mitteleuropäische Normalzeit) Atmosphere: Firing onReconnect
FlowClient-DKebW1gN.js:3352 Reopening push connection
vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342 Wed Dec 18 2024 18:36:34 GMT+0100 (Mitteleuropäische Normalzeit) Atmosphere: Firing onReconnect
vaadinPush.js?v=4d966870a796f3b21238e815a0e3a275915f5e8ff9e8ddd3212dbc5ead808229:3342 Wed Dec 18 2024 18:36:34 GMT+0100 (Mitteleuropäische Normalzeit) Atmosphere: ajaxrequest.onerror

If you now bring the connection back up in that state, extablishing the long-polling transport will eventually succeed. So now you're on long-polling even though you configured websocket and that would be supported by the browser.

Expected behavior

When the websocket is disconnected due to being offline, it should not be downgraded to long-polling. The long-polling fallback should only be used when websocket is not supported at all. If it has been established before and just disconnected for some reason, we know it is actually supported, so we don't have to resort to a fallback strategy, just wait for the device to be online again.

Ideally, the reconnection mechanism would use the "online" and "offline" events to understand whether/when the connection can be reestablished, but retrying in a loop is also fine.

Minimal reproducible example

This can be reproduced with a current Vaadin starter that is configured to use websocket for push. I use the default configuration WEBSOCKET_XHR, which is to use XHR for UIDL requests and websocket for push.

To reproduce, follow these steps:

  1. Open the app in your browser with dev tools opened.
  2. Wait for the websocket to be connected.
  3. Go offline (more on this below).
  4. Wait until you see in the browser console that websocket has been closed and is trying to reconnect (this was about 8 minutes for me).
  5. Wait a little longer until you see that it no longer tries websocket but long-polling instead.
  6. Go back online
  7. Now long-polling will be used for push instead of websocket.

Now for going offline, it didn't suffice to switch to offline mode in the dev tools for me. What I did instead to have the server run on one computer and connect from another notebook. Then I could switch off the WIFI of the notebook to actually go offline. This way, I could see the behavior described above.

Here is a complete version of my browser logs I obtained by executing these steps
console.log

Versions

  • Vaadin / Flow version: 24.6.0
  • Java version: openjdk version "21.0.5" 2024-10-15 LTS
    OpenJDK Runtime Environment Temurin-21.0.5+11 (build 21.0.5+11-LTS)
    OpenJDK 64-Bit Server VM Temurin-21.0.5+11 (build 21.0.5+11-LTS, mixed mode, sharing)
  • OS version: Windows 11
@mcollovati
Copy link
Collaborator

This is the expected behavior. Atmosphere client is configured to retry to reconnect the websocket for 12 times, with an interval of 5 seconds, then if downgrades to the fallback transport.

You can tune this behavior by setting the fallback transport to Websocket or setting the maxWebsocketErrorRetries property to a value higher than 12.

Both settings can be tuned using the PushConfiguration instance obtained from the UI instance.

UI.getPushConfiguration().setParameter("maxWebsocketErrorRetries", 10000);
UI.getPushConfiguration().setFallbackTransport(Transport.WEBSOCKET);

@mperktold
Copy link
Author

Wow, I didn't know about that.

I'll try this and see if it helps, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants