WebSockets were introduced to open two-way interactive communication sessions, between a client and a server. This paved the way for event-driven responses, such as notifying a user of new content without refreshing the page.
Dealing with WebSockets - Apache
Handling WebSockets in Apache Web Server 2.4 isn’t as straight forward as with other web servers. The Apache Config with a proxy pass will work most of the time
But when the web socket comes to picture, sometimes the site breaks in the browsers
In the below config we will assume you have already enabled proxy pass for a website. To enable WebSocket to reverse proxying, the Apache modules for handling such requests must be enabled.
Ubuntu
If you are running Ubuntu 16.04 or higher, run the following commands to enable the modules.
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_wstunnel
it will ask you to restart apache2. do it.
systemctl restart apache2
CentOS 7
The prerequisite modules are already enabled by default on a CentOS 7 install of httpd. Enabling and disabling these modules is done by editing a configuration file.
Open the module configuration file for proxies.
sudo vi /etc/httpd/conf.modules.d/00-proxy.conf
All modules related to proxying are listed in this configuration file. Verify that the following lines exist and are uncommented.
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_wstunnel modules/mod_proxy_wstunnel.so
If you made any changes to the file, save them now.
Restart Apache Web Server to apply your changes.
sudo systemctl restart httpd
mod_proxy = It provides support for the tunnelling of web socket connections to a backend websockets server. The connection is automatically upgraded to a websocket connection:
Things to be considered
Upgrade: WebSocket
Connection: Upgrade
Proxying requests to a websockets server like echo.websocket.org
can be done using the ProxyPass
directive:
ProxyPass "/ws2/" "ws://echo.websocket.org/"
ProxyPass "/wss2/" "wss://echo.websocket.org/"
Proxying both HTTP and websockets at the same time, with a specific set of URL's being websocket-only, can be done by specifying the websockets ProxyPass
directive before the HTTP directive:
ProxyPassMatch ^/(myApp/ws)$ ws://backend.example.com:9080/$1
ProxyPass / http://backend.example.com:9080/
Proxying both HTTP and websockets at the same time, where the websockets URL's are not websocket-only or not known in advance can be done by using the RewriteRule
directive to configure the websockets proxying:
ProxyPass / http://example.com:9080/
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) "ws://example.com:9080/$1" [P,L]
The web proxy port and host should be proper . add and save and restart httpd or Apache it should work properly
Note : if using proxy pass and websocket at same time the rewrite directive should be below proxypass directive.
Dealing with Websockets - Nginx
NGINX supports WebSocket by allowing a tunnel to be set up between a client and a backend server. For NGINX to send the Upgrade request from the client to the backend server, the Upgrade
and Connection
headers must be set explicitly, as in this example:-
location /wsapp/ {
proxy_pass http://wsbackend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
You also need to enable Connection and http upgrade in http section
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
You may also need to configure a upstream as below
upstream wsbackend {
server 192.168.100.10:8010;
}
8010 is port where ws is running
Reload nginx
systemctl reload nginx
Once this is done, NGINX deals with this as a WebSocket connection.
Visit the link for more info on Nginx Document . It's pretty straight forward .
HAProxy & Websockets
There are 2 protocols embedded in websockets:
HTTP: for the websocket setup
TCP: websocket data exchange
HAProxy must be able to support websockets on these two protocols without breaking the TCP connection at any time.
There are 2 things to take care of:
being able to switch a connection from HTTP to TCP without breaking it
smartly manage timeouts for both protocols at the same time
Fortunately, HAProxy embeds all you need to load-balance properly websockets and can meet the 2 requirements above.
It can even route regular HTTP traffic from websocket traffic to different backends and perform websocket aware health check (setup phase only).
During the setup phase, HAProxy can work in HTTP mode, processing layer 7 information. It detects automatically the Connection: Upgrade exchange and is ready to switch to tunnel mode if the upgrade negotiation succeeds. During this phase, there are 3 timeouts involved:
timeout client: client inactivity
timeout connect: allowed TCP connection establishment time
timeout server: allowed time to the server to process the request
If everything goes well, the websocket is established, then HAProxy fails over to tunnel mode, no data is analyzed anymore (and anyway, websocket does not speak HTTP). There is a single timeout involved:
timeout tunnel: take precedence over client and server timeout
timeout connect is not used since the TCP connection is already established.
Just make sure You have a following section in ha proxy config.
timeout client 25s
timeout connect 5s
timeout server 25s
timeout tunnel 3600s
timeout http-keep-alive 1s
timeout http-request 15s
Happy Dealing with websockets .
If you find it usefull . Follow me on github