Vaadin Flow Push Transport: WebSocket vs Long-Polling for Latency‑Constrained Deployments
0 reputation · 12 Jan 2025, 12:04 UTC
0 reputation · 12 Jan 2025, 12:04 UTC
Determine whether to rely on Vaadin Flow’s server‑side WebSocket push with automatic fallback to long‑polling, or to configure long‑polling as the primary transport when network latency is unpredictable and servlet container WebSocket support is limited.
Vaadin Flow does **not** guarantee a graceful switch on a live connection. After a WebSocket handshake fails, the client will retry the handshake. Only when that retry also fails will the client fall back to long‑polling on the *next* UI reconnect – which normally means a full page reload or an explicit UI.reconnect() call. In practice the connection remains stuck on WebSocket until the page is re‑loaded.
Use the hybrid transport @Push(transport = Transport.WEBSOCKET_XHR) (or Transport.XHR for pure long‑polling). Add a heartbeat interval (e.g., heartbeatInterval = 30) so the client can detect a broken WebSocket quickly. When the heartbeat fails, the client automatically switches to the XHR transport on the next poll, without requiring a page reload. Example:
@Push(transport = Transport.WEBSOCKET_XHR, heartbeatInterval = 30)
public class MyUI extends UI {
// UI code
}
Consider this path when:
ws:// or wss:// traffic.In these cases set @Push(transport = Transport.XHR) or use the property vaadin.pushMode=disabled in application.properties to avoid WebSocket altogether.
@Push is present.WEBSOCKET_XHR transport with heartbeat provides a quick fallback path.Run a simple Vaadin Flow app with @Push and check the server logs for "WebSocket handshake failed" entries. If you see repeated failures, the container likely lacks full support.
Inject a PushMessage that updates a timestamp in the UI and record the time between sending and rendering. If the average exceeds ~150 ms, consider long‑polling.
Apply the hybrid transport shown above and set heartbeatInterval to a value that balances quick detection with traffic overhead (e.g., 30 s).
Use browser dev tools or network emulation to block ws:// traffic and observe whether the UI recovers without a reload. Verify that XHR requests resume after the heartbeat failure.
Set @Push(transport = Transport.XHR) or vaadin.pushMode=disabled and redeploy. Confirm that updates arrive within acceptable latency and that server thread usage drops.
To fine‑tune the recommendation, could you share the average round‑trip latency you observe for WebSocket pushes in your production environment? This figure will help decide whether the 150 ms threshold is the right cut‑off for your case.
| Transport | Pros | Cons | When to Use |
|---|---|---|---|
| WebSocket (default) | Low latency, persistent connection | Requires full WebSocket support, higher server thread usage | Stable network, modern containers |
| WEBSOCKET_XHR (hybrid) | Automatic fallback, heartbeat‑driven detection | Extra HTTP overhead, still needs WebSocket support for the first attempt | Uncertain WebSocket support, need graceful fallback |
| Long‑Polling (XHR) | Works everywhere, low thread count | Higher latency, more HTTP traffic | Containers lacking WebSocket, high latency environments |
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.