HTTP fallback
When a network blocks WebSockets, the chat automatically continues over plain HTTPS – when this happens, how to force it, what your Content Security Policy and your proxy need, troubleshooting.
The widget normally connects to the chat server via WebSocket. Some networks do not allow that. For this case there is the HTTP fallback: the chat then continues over ordinary HTTPS requests, without you or your visitors having to do anything.
What the HTTP fallback is
WebSocket connections typically fail:
- in corporate networks whose proxy or firewall only lets ordinary HTTP(S) requests through,
- with hosting providers, CDNs or load balancers that do not forward WebSockets,
- behind a reverse proxy that does not pass on the
UpgradeandConnectionheaders.
In the HTTP fallback the widget receives the server's messages as Server-Sent Events (a long-lived HTTPS stream). If nothing arrives over this stream, it switches to long polling. Sending uses HTTPS POST. Both routes carry the same messages as the WebSocket: your visitors write, receive the answers of the AI assistant and of your agents, and several open tabs share one connection as usual. File attachments are uploaded over HTTPS anyway and do not depend on the connection type.
The fallback applies to the chat widget on your website. Your agents' interface still connects via WebSocket.
When it applies
The widget uses the HTTP fallback when
- the browser does not support WebSockets,
- two WebSocket connection attempts fail in a row – an attempt that has neither been established nor rejected after 8 seconds also counts as failed,
- you force it (see below).
The switch only happens as long as no WebSocket connection has been established on the page. If an existing WebSocket connection drops, for example because the network changes, the widget reconnects via WebSocket.
Once the fallback is active, the widget stays with it for this page. So that following pages do not lose two attempts again, it remembers the switch: pages opened in the same tab within 30 minutes connect over HTTPS directly. At the same time the widget checks once per page in the background whether a WebSocket now gets through. If it does, the next page uses the WebSocket again; the current page stays on the HTTP fallback.
Forcing the fallback
For tests or for environments where WebSockets are known not to work, you can switch the HTTP fallback on from the start. The simplest way is the attribute data-rc-transport="http" on the widget's script tag:
<script src="https://cdn.reactive.chat/loader.js"
data-rc-site-key="SITE_KEY"
data-rc-transport="http"
async></script>
The widget looks for the attribute in the whole document, so it also works on another element as long as that element is already in the document when the widget starts.
Alternatively, set the option in JavaScript, before the widget's script tag:
<script>
window.ReactiveChatSettings = { transport: 'http' };
</script>
<script src="https://cdn.reactive.chat/loader.js"
data-rc-site-key="SITE_KEY"
async></script>
A later call of ReactiveChat('boot', { transport: 'http' }) has no effect on this: the connection type is fixed when the widget starts.
Content Security Policy
Server-Sent Events, long polling and sending use the same address as the chat connection, only with https:// instead of wss://. If your website sets a Content Security Policy, connect-src therefore has to allow both forms:
connect-src 'self' wss://ws.reactive.chat https://ws.reactive.chat
The offline form and file uploads also use the https:// address. With your own domain, the addresses of your subdomain go there:
connect-src 'self' wss://chat.your-domain.com https://chat.your-domain.com
Other entries of your policy stay as they are. What else the policy has to allow is described in Embedding the widget.
With your own domain
If you run the chat through a subdomain of your website, the HTTP fallback uses the same path /rc_wss/ as the WebSocket. Your proxy needs no additional path for it, but it must pass on the responses on this path without buffering:
- nginx:
proxy_buffering offandproxy_cache offin the/rc_wss/section, - Apache:
flushpackets=onon theProxyPassline for/rc_wss/, - Caddy:
flush_interval -1in thereverse_proxyfor/rc_wss/.
The templates on the account page and in the own domain guide already contain these settings. If you took over an older configuration, compare it with the current template.
What is stored in the browser
After a successful connection over HTTPS, the widget creates the entry rc_http in the browser's sessionStorage. It contains only the time of that connection and no personal data. The widget uses it so that following pages go straight to the HTTP fallback for 30 minutes; once the WebSocket gets through again, it deletes the entry. Like every sessionStorage entry, it disappears at the latest when the tab is closed. If sessionStorage is not available, for example in some private windows, every page starts with the WebSocket again.
Which route is active
Open the browser's developer tools and go to the "Network" tab:
- WebSocket: there is a connection of type WebSocket to
wss://ws.reactive.chat/rc_wss/(with your own domain, to your subdomain). - HTTP fallback: there are requests to
https://ws.reactive.chat/rc_wss/h/…– firsth/auf, then a long-running stream on…/sse(with long polling, recurring requests on…/poll) and one request on…/txfor every message sent.
Under "Application" or "Storage" you can also see whether the entry rc_http is set.
Troubleshooting
The Content Security Policy blocks the https address
If connect-src only lists the wss:// address, the browser blocks the fallback's requests. The browser console then shows a CSP message about https://…/rc_wss/h/auf. Where the WebSocket gets through you will not notice anything – but in networks without WebSocket no connection is established at all. Add the https:// address as shown above.
A proxy buffers the responses
If a proxy on the way buffers the stream, the Server-Sent Events arrive late, in batches, or not at all. The widget waits 5 seconds for the first message over the stream and then switches to long polling. The chat works that way, but setting up the connection takes a few seconds longer. With your own domain, switch off buffering for /rc_wss/ (see above).
Long-running requests are cut off
With long polling, the server keeps a request open for up to 25 seconds when there is nothing to report. Over an open stream it sends a keep-alive signal every 15 seconds. Firewalls or proxies that abort requests earlier force the widget to reconnect frequently. Allow requests to the chat address to last at least 30 seconds.
The chat does not connect at all
If both WebSocket and HTTP fallback fail, the widget keeps trying in the background. Check whether the chat address can be reached over HTTPS at all from your visitors' network and whether a Content Security Policy or a filter blocks it.
Last updated: