Deploying Vaadin Applications Behind Reverse Proxies
- Apache HTTPD
nginx- WebSockets in a Vaadin Application
- Server-Sent Events in a Vaadin Application
- Compression and Push
- Deployment Scenarios
- Proxying Multiple Backend Vaadin Application
- Push Connection Timeout
Using a reverse proxy in front of a Java servlet container, such as Apache HTTPD with Tomcat or Jetty, is widely considered a best practice for deploying web applications. A reverse proxy acts as an intermediary between clients and the backend application server, offering numerous benefits that enhance performance, security, and scalability.
By offloading tasks like SSL termination, request routing, and caching to the reverse proxy, the servlet container can focus on serving application logic, resulting in a more efficient and maintainable deployment architecture. Additionally, reverse proxies provide a unified interface for serving multiple applications, enabling load balancing, URL rewriting, and seamless integration of static content alongside dynamic applications.
Security is another key advantage, as the reverse proxy can filter incoming requests, prevent direct exposure of the application server to the internet, and enforce access controls. This layer of abstraction not only simplifies scaling and maintenance but also enhances the reliability and robustness of your Java-based web applications.
This guide covers common deployment scenarios, configuration for reverse proxies, and special considerations for Vaadin’s server push functionality, session handling, and load balancing. It explains how to configure Vaadin applications to work seamlessly behind reverse proxies.
Various configuration scenarios are implemented using Apache HTTPD (2.4.47+) and nginx. The provided configurations are a working starting point that can be improved with specific customization for the production environment.
Apache HTTPD
Proxying with Apache HTTPD is additionally expanded into two categories: HTTP and AJP backend protocols. Apache HTTPD should be configured to load mod_rewrite, mod_proxy, and one or more proxy modules, such as mod_proxy_http, mod_proxy_wstunnel or mod_proxy_ajp.
Source code
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
# Optional, for AJP backend protocol
# LoadModule proxy_ajp_module modules/mod_proxy_ajp.soExample snippets are limited to the proxy configuration. In the simplest cases all relevant configurations are put into a <Location> directive. However, setups that require mod_rewrite should be directly used inside server config or virtual host definition.
The proxying directives used in the examples are the following:
-
ProxyPass: maps remote servers into the local server URL-space. -
ProxyPassReverse: adjusts the URL in HTTP response headers sent from a reverse proxied server. -
ProxyPassReverseCookiePath: adjusts the Path string inSet-Cookieheaders from a reverse-proxied server.
ProxyPass directive can take a list of parameters in form of key=value pairs to tune the connection to the backend server. For simplicity, the examples won’t set any option, but with complex network setup, it might be useful to configure some of them:
-
keepalive=On: should be used when you have a firewall between your Apache HTTPD and the backend server, which tends to drop inactive connections. -
disablereuse=On: forcemod_proxyto immediately close a connection to the backend after being used, and thus, disable its persistent connection and pool for that backend. This helps in various situations where a firewall between Apache HTTPD and the backend server (regardless of protocol) tends to silently drop connections. -
retry=0: prevents Apache waiting for a while before sending request again to the backend server in case the worker is an error state.
Also, only Location, Content-Location and URI headers in the HTTP response is rewritten by ProxyPassReverse. Apache HTTPD won’t rewrite other response headers, nor does it by default rewrite URL references inside HTML pages. This means that if the proxied content contains absolute URL references, they’ll bypass the proxy. To rewrite HTML content to match the proxy, you must load and enable mod_proxy_html.
AJP Protocol
The Apache JServ Protocol (AJP) is a binary protocol commonly used to connect web servers and application servers. It can be an efficient alternative to HTTP(S) in certain scenarios, such as when reducing overhead is important or when working with legacy systems.
In a Spring Boot application with embedded Apache Tomcat servlet container, AJP support can be configured as following:
Source code
Java
@ConditionalOnProperty("tomcat.ajp.port")
@Configuration
public class TomcatConfig implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
private static final String PROTOCOL = "AJP/1.3";
@Value("${tomcat.ajp.port:8009}") //Defined on application.properties or as environment variable
private int ajpPort;
@Value("${tomcat.ajp.address:::}") //Defined on application.properties or as environment variable
private InetAddress ajpAddress;
@Value("${tomcat.ajp.secret}") // Defined on application.properties or as environment variable
private String ajpSecret;
@Override
public void customize(TomcatServletWebServerFactory factory) {
Connector ajpConnector = new Connector(PROTOCOL);
ajpConnector.setPort(ajpPort);
AbstractAjpProtocol<?> ajpProtocol = (AbstractAjpProtocol<?>) ajpConnector.getProtocolHandler();
ajpProtocol.setSecret(ajpSecret);
ajpProtocol.setAddress(ajpAddress);
factory.addAdditionalConnectors(ajpConnector);
}
}To enhance security, the above snippet is setting the AJP protocol secret, that should be included with every request from the proxy server.
In the Apache HTTPD configuration examples, the value of the secret is supposed to be stored in an environment variable named VAADIN_APP_AJP_SECRET.
For different setups, consult the documentation of the Servlet container.
AJP can’t carry WebSocket traffic, so the examples in this guide proxy the push endpoint over HTTP with a separate set of directives whenever WebSockets are in use. With the Server-Sent Events transport, that second channel isn’t needed: the push request travels over the AJP connection together with every other request, and the HTTP port of the backend server doesn’t have to be reachable from the proxy at all. The AJP worker has to be configured with flushpackets=on, because mod_proxy_ajp otherwise buffers the response body and holds back the stream.
Note that a ws:// worker serves WebSocket traffic only, and rejects the plain GET request that Server-Sent Events uses. Where the examples route the push path to such a worker, the two transports are mutually exclusive: remove those rules to serve push over AJP. Where the upgrade is instead selected by a RewriteCond on the Upgrade request header, both transports are served by the same configuration, since requests without that header continue to the AJP worker.
nginx
The nginx examples are mostly based on the online WebSocket proxying guide. The provided code snippets are supposed to be placed into the http block in the main configuration file.
Source code
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
http {
## Example snippet goes here
}A map directive is used to handle the connection upgrade, to set the value of the Connection header field in a request to the proxied server depending on the presence of the Upgrade field in the client request header.
Source code
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}Other used directive are:
-
proxy_pass: maps remote servers into the local server URL-space. -
proxy_set_header: redefines or appends fields to the request header passed to the proxied server. -
proxy_redirect: adjusts the URL in HTTP response headers sent from a reverse proxied server. -
proxy_cookie_path: adjusts the Path string inSet-Cookieheaders from a reverse-proxied server.
WebSockets in a Vaadin Application
WebSockets provide a persistent, full-duplex communication channel between a client and a server, unlike traditional HTTP requests, which follow a request-response model. In the context of a Vaadin application, WebSockets are optional but enhance user experience by enabling (server push), allowing real-time UI updates without requiring clients to repeatedly poll the server.
WebSockets work by performing a protocol upgrade from HTTP to the WebSocket protocol (ws:// or wss://) using the Upgrade and Connection headers.
In Apache HTTPD WebSocket proxying is usually achieved by adding the upgrade=websocket option to the ProxyPass directive.
However, AJP does not support WebSockets because it is designed for traditional request-response communication and does not handle persistent bidirectional connections.
The examples in this guide work around this limitation by proxying the upgrade requests over HTTP with a dedicated set of directives, which requires the HTTP port of the backend server to be reachable from the proxy.
The Server-Sent Events transport is not affected, since it travels over an AJP connection like any other request.
To support WebSockets behind a reverse proxy, Apache must route WebSocket traffic ensuring proper handling of the upgrade process and maintaining the connection between the client and the backend Vaadin server, meaning that a specific configuration is required.
Similarly, nginx also needs to be configured to handle the protocol upgrade. In the proposed example, the WebSockets configuration blocks are marked with Websockets only (begin) and Websockets only (end) comments.
If WebSockets support is not required by the application, the related configuration can be skipped. For Apache HTTPD ProxyPass directive remove the upgrade option.
|
Warning
|
In Apache HTTPD, a ProxyPass rule for the push endpoint is ignored when a catch-all rule using the same URL scheme is declared before it. mod_proxy shares workers whose URLs overlap and keeps the one defined first, so the upgrade=websocket option on the push rule is silently discarded and the upgrade never happens. The mod_proxy documentation recommends sorting worker definitions by URL length, starting with the longest. For this reason, the examples in this guide declare the push locations before the catch-all. The ProxyPassReverse directive doesn’t create a worker and isn’t affected.
|
Server-Sent Events in a Vaadin Application
Server-Sent Events (SSE) is an alternative transport for PUSH communication, available behind the ssePushTransport feature flag. Rather than upgrading the connection, the browser sends a long-lived HTTP GET request to the push endpoint, and the server streams updates over the response until the connection is closed. Messages from the client to the server travel over regular XHR requests, as they do with the default WEBSOCKET_XHR transport.
Since SSE is plain HTTP, none of the WebSocket-specific configuration applies to it. Apache HTTPD needs neither mod_proxy_wstunnel nor the upgrade option on ProxyPass, and nginx needs neither the map $http_upgrade directive nor the Upgrade and Connection request headers. The push endpoint is the same /VAADIN/push path, so the location patterns already used for WebSockets match SSE traffic without changes.
What SSE requires instead is that the proxy forwards the response as it arrives. Proxy defaults tend to work against this, because a streaming response gets buffered, possibly compressed, and closed once it has been idle for long enough:
-
Response buffering is the main obstacle. A buffering proxy waits for the buffer to fill, or for the response to end, before forwarding anything, and an SSE response never ends. In
nginx,proxy_bufferingis enabled by default and has to be turned off. In Apache HTTPD,mod_proxy_httpforwards the backend flushes as they happen, butmod_proxy_ajpbuffers the response body unlessflushpackets=onis set on the worker. -
Compression doesn’t hold the stream back on its own, since
mod_deflateand thenginxgzip filter both flush per event, but it should still be kept off the push response. See Compression and Push. -
The HTTP version to the backend matters for
nginx, which uses HTTP/1.0 upstream unlessproxy_http_version 1.1is set. -
Idle timeouts close a stream that has been silent, as described in Push Connection Timeout.
|
Warning
|
A proxy that buffers the push response breaks server push silently. The connection is established, the server writes updates, and the browser receives them much later or not at all, with nothing in the logs to indicate a problem. Atmosphere pads the beginning of the stream with 2000 bytes to flush proxy buffers, but that’s less than the 4 KB default proxy_buffer_size of nginx, so it doesn’t compensate for a missing proxy_buffering off.
|
In the configuration examples, the SSE-specific configuration is marked with Server-sent events only comments: a (begin) and (end) pair where it consists of several directives, as in the nginx examples, and a single comment line where it’s one option added to an existing directive, as with flushpackets=on on the AJP workers. Apache HTTPD over HTTP carries no such marker, since its defaults already suit a streaming response, apart from the timeout.
When the proxy terminates TLS, X-Forwarded-Proto matters as much as it does for WebSockets, for a different reason. Vaadin builds the push URL from the advertised scheme, and a page served over https isn’t allowed to open an http:// event stream, as the browser blocks it as mixed content. Configure the backend server to honor the forwarded headers, for example with SERVER_FORWARD_HEADERS_STRATEGY=NATIVE in a Spring Boot application.
Sticky sessions are required exactly as they are for the other transports. The SSE stream and the client-to-server XHR requests are separate connections that have to reach the same backend node. See Load Balancing with Sticky Session.
Browser Connection Limits
Browsers allow a limited number of concurrent HTTP/1.1 connections to the same origin, typically six, and an open SSE stream occupies one of them for as long as the tab stays open. WebSocket connections aren’t counted against this pool, so the limit affects SSE and long polling only. With several tabs of the same application open, regular requests can end up queued behind the streams, and the application appears to freeze. Serving the application over HTTP/2 between the browser and the proxy removes the limit. The connection between the proxy and the backend server can stay on HTTP/1.1.
Hilla Reactive Endpoints
Browser-callable Hilla methods that return a Flux use a separate push connection on the /HILLA/push path. That connection isn’t controlled by the Flow push configuration and always uses WebSockets. A proxy that can’t carry WebSocket traffic therefore supports Flow server push over SSE, but not Hilla reactive endpoints. Regular browser-callable methods aren’t affected, as they’re plain HTTP requests.
Verifying the Push Transport
The push endpoint can be tested without a browser, by requesting it the way the client does:
Source code
bash
curl -N -i "http://proxy/VAADIN/push?v-r=push&X-Atmosphere-Transport=sse&X-Atmosphere-tracking-id=0"A correctly configured proxy responds with 200 and a Content-Type: text/event-stream header, and the response stays open. Compare the output with the same request sent directly to the backend server: if the proxy delivers in bursts what the backend server delivers gradually, the response is being buffered.
In the browser development tools, the push request must show the text/event-stream content type and remain pending while data arrives. Verifying that the application behaves correctly isn’t sufficient, because Atmosphere falls back to another transport when the selected one fails, and the application keeps working. To make such a failure visible while testing a proxy configuration, set the fallback transport to the same value as the transport.
Selecting a WebSocket transport against a proxy that’s configured for SSE only fails with Error during WebSocket handshake: Unexpected response code: 501. The Upgrade and Connection headers are hop-by-hop headers that the proxy doesn’t forward, so the backend server receives a request that claims the WebSocket transport without an actual upgrade, and rejects it. This is the expected behavior rather than a misconfiguration.
Compression and Push
Compression can be left enabled, as long as it doesn’t apply to a streamed response. Vaadin PUSH answers with the text/event-stream content type over Server-Sent Events, and with text/plain over streaming and long polling. Keeping both out of the list of compressed content types is what matters, and it’s more dependable than excluding a path, since it holds wherever the push endpoint is mapped.
Source code
Apache HTTPD
<IfModule deflate_module>
AddOutputFilterByType DEFLATE text/html text/css text/xml \
application/javascript application/json \
application/xml image/svg+xml
# For paths whose response type isn't known in advance: an EventSource
# always asks for text/event-stream, and the push endpoints stream
# whatever they answer with.
SetEnvIfNoCase Accept text/event-stream no-gzip=1
SetEnvIfNoCase Request_URI "/(VAADIN|HILLA)/push" no-gzip=1
</IfModule>nginx
nginxAvoid a wildcard such as AddOutputFilterByType DEFLATE text/*, which matches both of the content types used by push. In nginx, text/html is always compressed when gzip is enabled and can’t be removed from gzip_types, which is harmless here because a push response is never text/html.
Compressing the stream doesn’t stall it, because both compressors flush after each event, so the updates still arrive one at a time as long as proxy_buffering off or flushpackets=on is in place. It’s worth avoiding for two other reasons:
-
A compression context stays allocated for the whole life of every push connection, which is the whole life of every open browser tab.
-
The 2000 bytes of padding that Atmosphere writes when a stream opens exist to force a buffering intermediary to flush. Compressed, those 2000 identical characters shrink to a few dozen bytes and stop serving that purpose, so the deployment breaks as soon as another buffering hop appears in front of the proxy.
Deployment Scenarios
The next sections provide configuration examples covering the following deployment scenarios:
| Scenario | Public URL | Internal Vaadin Application URL |
|---|---|---|
Web Server and Vaadin application on root context. |
| |
Web Server and Vaadin application on a sub context. |
| |
Web Server on root context and Vaadin application on sub context. |
| |
Web Server on sub context and Vaadin application on root context. |
| |
Load Balancing with Sticky Session. |
|
All the scenarios assume the Vaadin application is built for production and PUSH communication is enabled. Configuration that applies only to a specific push transport is marked with Websockets only and Server-sent events only comments. It’s usually better to deploy the application on the backend server at the same path as the proxy rather than to take this approach, to avoid potential issues with URLs sent back to the client as HTTP headers or in the response body.
Web Server & Vaadin on Root Context
This is the most straightforward scenario, where a backend application served on the root context is published as-is on the internet, meaning that the browser requests to http(s)://proxy/ are forwarded to http://vaadin-app:8080.
Source code
Apache HTTPD
<Location />
ProxyPass http://vaadin-app:8080/ upgrade=websocket
ProxyPassReverse http://vaadin-app:8080/
</Location>Apache HTTPD - AJP
nginx
nginxAs an alternative, the push endpoint can be given its own configuration, instead of applying the same settings to the whole application. This setup requires dedicated rules for both the Flow and the Hilla push endpoints. With WebSockets, it limits the protocol upgrade to those paths. With Server-Sent Events, it limits the cost of disabled response buffering to the streaming response.
Source code
Apache HTTPD
# -- Websockets only (begin)
# Must be declared before the catch-all rule, see the warning on mod_proxy worker sharing.
<Location /VAADIN/push>
ProxyPass http://vaadin-app:8080/VAADIN/push upgrade=websocket
</Location>
<Location /HILLA/push>
ProxyPass http://vaadin-app:8080/HILLA/push upgrade=websocket
</Location>
# -- Websockets only (end)
<Location />
ProxyPass http://vaadin-app:8080/
ProxyPassReverse http://vaadin-app:8080/
</Location>Apache HTTPD - AJP
nginx
nginxWeb Server & Vaadin on Sub-Context
Similar to the previous scenario, but the Vaadin application is reachable on the same sub path on both the reverse proxy and the backend server. In this case http(s)://proxy/app/ forwards to http://vaadin-app:8080/app/.
Source code
Apache HTTPD
<Location /app/>
ProxyPass http://vaadin-app:8080/app/ upgrade=websocket
ProxyPassReverse http://vaadin-app:8080/app/
</Location>Apache HTTPD - AJP
nginx
nginxAs an alternative, the push endpoint can be given its own configuration, instead of applying the same settings to the whole application. This setup requires dedicated rules for both the Flow and the Hilla push endpoints. With WebSockets, it limits the protocol upgrade to those paths. With Server-Sent Events, it limits the cost of disabled response buffering to the streaming response.
Source code
Apache HTTPD
# -- Websockets only (begin)
# Must be declared before the catch-all rule, see the warning on mod_proxy worker sharing.
<Location /app/VAADIN/push>
ProxyPass http://vaadin-app:8080/app/VAADIN/push upgrade=websocket
</Location>
<Location /app/HILLA/push>
ProxyPass http://vaadin-app:8080/app/HILLA/push upgrade=websocket
</Location>
# -- Websockets only (end)
<Location /app/>
ProxyPass http://vaadin-app:8080/app/
ProxyPassReverse http://vaadin-app:8080/app/
</Location>Apache HTTPD - AJP
nginx
nginxWeb Server on Root Context & Vaadin on Sub-Context
In this scenario the backend application is published on a sub context, but the proxy is reachable on the root context. Therefore, a request to http(s)://proxy/ is forwarded to http://vaadin-app/app/. Since paths don’t match, the reverse proxy must also rewrite the cookie paths.
Source code
Apache HTTPD
<Location />
ProxyPass "http://vaadin-app:8080/app/" upgrade=websocket
ProxyPassReverse "http://vaadin-app:8080/app/"
ProxyPassReverseCookiePath "/app" "/"
</Location>Apache HTTPD - AJP
nginx
nginxAs an alternative, the push endpoint can be given its own configuration, instead of applying the same settings to the whole application. This setup requires dedicated rules for both the Flow and the Hilla push endpoints. With WebSockets, it limits the protocol upgrade to those paths. With Server-Sent Events, it limits the cost of disabled response buffering to the streaming response.
Source code
Apache HTTPD
# -- Websockets only (begin)
# Must be declared before the catch-all rule, see the warning on mod_proxy worker sharing.
<Location /VAADIN/push>
ProxyPass "http://vaadin-app:8080/app/VAADIN/push" upgrade=websocket
</Location>
<Location /HILLA/push>
ProxyPass "http://vaadin-app:8080/app/HILLA/push" upgrade=websocket
</Location>
# -- Websockets only (end)
<Location />
ProxyPass "http://vaadin-app:8080/app/"
ProxyPassReverse "http://vaadin-app:8080/app/"
ProxyPassReverseCookiePath "/app" "/"
</Location>Apache HTTPD - AJP
nginx
nginxWeb Server on Sub-Context & Vaadin on Root Context
This is the opposite of the above scenario. The proxy server exposes the application on a sub context but it forwards the request to the backed server root path, for example http(s)://proxy/app/ to http://vaadin-app:8080/. As in the previous case, the proxy server must rewrite the cookie path.
Source code
Apache HTTPD
<Location /app/>
ProxyPass "http://vaadin-app:8080/" upgrade=websocket
ProxyPassReverse "/"
ProxyPassReverseCookiePath "/" "/app"
</Location>Apache HTTPD - AJP
nginx
nginxAs an alternative, the push endpoint can be given its own configuration, instead of applying the same settings to the whole application. This setup requires dedicated rules for both the Flow and the Hilla push endpoints. With WebSockets, it limits the protocol upgrade to those paths. With Server-Sent Events, it limits the cost of disabled response buffering to the streaming response.
Source code
Apache HTTPD
# -- Websockets only (begin)
# Must be declared before the catch-all rule, see the warning on mod_proxy worker sharing.
<Location /app/VAADIN/push>
ProxyPass "http://vaadin-app:8080/VAADIN/push" upgrade=websocket
</Location>
<Location /app/HILLA/push>
ProxyPass "http://vaadin-app:8080/HILLA/push" upgrade=websocket
</Location>
# -- Websockets only (end)
<Location /app/>
ProxyPass "http://vaadin-app:8080/"
ProxyPassReverse "/"
ProxyPassReverseCookiePath "/" "/app"
</Location>Apache HTTPD - AJP
nginx
nginxLoad Balancing with Sticky Session
Load balancing is a critical mechanism for ensuring high availability, scalability, and fault tolerance in web applications. By distributing incoming client requests across multiple backend servers, load balancing improves application responsiveness and prevents any single server from becoming a bottleneck.
For Vaadin applications, which maintain long-lived user sessions due to their stateful nature, implementing load balancing with sticky sessions becomes essential. Sticky sessions, also known as session affinity, ensure that each user’s requests are consistently routed to the same backend server, preserving the application state and avoiding issues caused by session deserialization across servers.
For Apache HTTPD, you need to load the mod_proxy_balancer module and at least one module providing a scheduler algorithm. The example in this guide use mod_lbmethod_byrequests that distributes the requests among the various workers to ensure that each gets their configured share of the number of requests.
Depending on the Apache server global setup, you may need to load also mod_slotmem_shm, used internally by other modules.
Source code
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.soSticky sessions are managed using a custom ROUTEID cookie, simplifying configuration and ensuring proper session affinity without relying on backend modifications like adding a jvmRoute to Tomcat configuration.
For nginx, cookie based sticky sessions are available in the open-source version since nginx 1.29.6. In earlier versions, the sticky directive was available only as part of the commercial subscription.
If you’re running an nginx version older than 1.29.6, you can use the ip_hash directive instead. It uses the client IP address as a hashing key to determine which server in a server group should be selected for the client requests. The main drawback of the ip_hash approach is that it doesn’t work well for clients behind proxies or NAT, since many clients share the same IP.
Source code
Apache HTTPD
<Proxy "balancer://application-balancer/">
BalancerMember "http://vaadin-app-1:8080" route=1 upgrade=websocket
BalancerMember "http://vaadin-app-2:8080" route=2 upgrade=websocket
ProxySet stickysession=ROUTEID
ProxySet lbmethod=byrequests
</Proxy>
<Location / >
# Adding a cookie for session affinity instead of backend JSESSIONID because:
# - additional configuration required on the backend server to add the route id
# in the cookie value (e.g. jvmRoute for Tomcat)
# - The backend cookie might not be set on the very first request, causing unexpected behaviors
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/; HttpOnly" env=BALANCER_ROUTE_CHANGED
ProxyPass "balancer://application-balancer/"
ProxyPassReverse "balancer://application-balancer/"
</Location>Apache HTTPD - AJP
nginx
nginxProxying Multiple Backend Vaadin Application
All proposed configurations can be applied when the reverse proxy exposes multiple backend Vaadin applications. In a similar setup, it’s important that all backend applications define different cookie names, otherwise the proxy overwrites the same cookie with different values, preventing the Vaadin applications from working correctly.
In a Spring Boot application, the cookie name can be set with the server.servlet.session.cookie.name property. Another possibility is to set programmatically the name in a Servlet listener by getting the SessionCookieConfig instance from the ServletContext and use the setName(String) method to change cookie name.
Push Connection Timeout
By default, the push connection is closed if the proxied server doesn’t transmit any data within sixty seconds. Vaadin PUSH is configured to send a heartbeat message every sixty seconds, so the connection should not be closed. If the default is not working correctly, the timeout can be increased in both Apache HTTPD and nginx by applying the appropriate configuration.
The default of sixty seconds is exactly the heartbeat interval, which leaves no margin at all. For this reason, the examples raise it to three hundred seconds.
The timeout applies to every push transport, but the consequences differ. A WebSocket or long polling connection that the proxy closes is re-established by Atmosphere. A Server-Sent Events stream is reopened by the browser instead, which issues a new server request each time and can lose messages in between, making the problem easy to overlook.
Source code
Apache HTTPD
ProxyPass / http://vaadin-app:8080/ upgrade=websocket timeout=300
# In alternative, use ProxyTimeout directive
# ProxyTimeout 300nginx
nginxIn nginx, a directive set in an enclosing block applies only when the same directive isn’t set at a more specific level. When the push endpoint has a location block of its own, set proxy_read_timeout inside that block.
0C8F77AE-16A8-463B-8F43-1C9F3A7DF1E2