Jay Taylor's notes
back to listing indexWebSockets and Apache proxy : how to configure mod_proxy_wstunnel?
[web search]- Home
-
- Public
- Stack Overflow
- Tags
- Users
- Jobs
-
- Teams
- Create Team
I have :
Apache
(v2.4) on port 80 of my server forwww.domain1.com
, with mod_proxy and mod_proxy_wstunnel enablednode.js + socket.io
on port 3001 of the same server.
Accessing www.domain2.com
(with port 80) redirects to 2. thanks to the method described here. I have set this in the Apache configuration:
<VirtualHost *:80>
ServerName www.domain2.com
ProxyPass / http://localhost:3001/
ProxyPassReverse / http://localhost:3001/
ProxyPass / ws://localhost:3001/
ProxyPassReverse / ws://localhost:3001/
</VirtualHost>
It works for everything, except the websocket part : ws://...
are not transmitted like it should by the proxy.
When I access the page on www.domain2.com
, I have:
Impossible to connect ws://www.domain2.com/socket.io/?EIO=3&transport=websocket&sid=n30rqg9AEqZIk5c9AABN.
Question: How to make Apache proxy the WebSockets as well?
I finally managed to do it, thanks to this topic.
TODO:
1) Have Apache 2.4 installed (doesn't work with 2.2), and do:
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_wstunnel
2) Have nodejs
running on port 3001
3) Do this in the Apache config
<VirtualHost *:80>
ServerName www.domain2.com
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:3001/$1 [P,L]
ProxyPass / http://localhost:3001/
ProxyPassReverse / http://localhost:3001/
</VirtualHost>
Note: if you have more than one service on the same server that uses websockets, you might want to do this to separate them.
-
FWIW, Apache 2.4 in CentOS 7.1 has this bug therefore rewrite won't recognize ws:// protocol, and prepends the domain before sending the subrequest. You can test yourself by changing the [P]roxy flag to [R]edirect. – Andor Jul 23 '15 at 15:34
-
3I still get 502 bad gateway for my ws:// routes when doing this. Running Apache 2.4 on Ubuntu 14.04 – Alex Muro Sep 10 '15 at 18:32
-
1
-
1
-
1
Instead of filtering by URL, you can also filter by HTTP header. This configuration will work for any web applications that use websockets, also if they are not using socket.io:
<VirtualHost *:80>
ServerName www.domain2.com
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:3001/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) http://localhost:3001/$1 [P,L]
ProxyPassReverse / http://localhost:3001/
</VirtualHost>
-
1RewriteCond %{HTTP:Upgrade} !^websocket$ [NC] some browsers will type websocket and some Websocket. That is why the NC (no case) option is needed – Didac Montero Jul 22 '16 at 12:46
-
-
@cdauth Worked for me proxying peer.js that for my webrtc app. Thanks! – ingridsede Sep 7 '16 at 12:57
-
This is working fine for me but I'm proxying a subpath and I've found it's important to add the ^ anchors since the regex is looking for a substring. E.g. RewriteRule ^[^/]*/foo/(.*) http://${FOO_HOST}/$1 [P,L] (otherwise /bar/foo will also be directed to the same place as /foo) – Steve Lilly Sep 10 '16 at 9:50
-
2
May be will be useful. Just all queries send via ws to node
<VirtualHost *:80>
ServerName www.domain2.com
<Location "/">
ProxyPass "ws://localhost:3001/"
</Location>
</VirtualHost>
-
Thanks @Sergey. This helped me when I only used the direct path referenced by ws instead of routing everything to document root. I've shown what I've done in an answer below for the benefit of others. – Anwaarullah Sep 27 '15 at 7:13
-
This answer works for simple web sockets (no socket.io) so for me this is better answer – Tomas Feb 3 '16 at 9:42
-
Awesome! This was instantly working for me while the other rewrite and proxy attempts did'nt solve my problem. – Stephan Mar 11 '16 at 13:11
-
It works for me after spend hours for test more than 100 solution – vietnguyen09 Jun 16 '16 at 15:56
-
You my friend are a life-saver. Don't know how many solutions I tried....Thanks a lot.. :D – We are Borg Nov 8 '17 at 9:27
As of Socket.IO 1.0 (May 2014), all connections begin with an HTTP polling request (more info here). That means that in addition to forwarding WebSocket traffic, you need to forward any transport=polling
HTTP requests.
The solution below should redirect all socket traffic correctly, without redirecting any other traffic.
Enable the following Apache2 mods:
sudo a2enmod proxy rewrite proxy_http proxy_wstunnel
Use these settings in your *.conf file (e.g.
/etc/apache2/sites-available/mysite.com.conf
). I've included comments to explain each piece:<VirtualHost *:80> ServerName www.mydomain.com # Enable the rewrite engine # Requires: sudo a2enmod proxy rewrite proxy_http proxy_wstunnel # In the rules/conds, [NC] means case-insensitve, [P] means proxy RewriteEngine On # socket.io 1.0+ starts all connections with an HTTP polling request RewriteCond %{QUERY_STRING} transport=polling [NC] RewriteRule /(.*) http://localhost:3001/$1 [P] # When socket.io wants to initiate a WebSocket connection, it sends an # "upgrade: websocket" request that should be transferred to ws:// RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteRule /(.*) ws://localhost:3001/$1 [P] # OPTIONAL: Route all HTTP traffic at /node to port 3001 ProxyRequests Off ProxyPass /node http://localhost:3001 ProxyPassReverse /node http://localhost:3001 </VirtualHost>
I've included an extra section for routing
/node
traffic that I find handy, see here for more info.
My setup:
Apache 2.4.10 (running off Debian) NodeJS (version 4.1.1) App running on port 3000 that accepts WebSockets at path /api/ws
As mentioned above by @Basj, make sure a2enmod proxy and ws_tunnel are enabled.
This is a screengrab of the Apache conf file that solved my problem:
Hope that helps.
-
I'm having trouble setting up my app with a prefered URL rather than the default, would you mind helping me out? (I'm sitting on top of a varnish cache server) – Josh Dec 30 '15 at 1:01
-
Could you copy/paste instead of screenshot? Thank you in advance, it would improve readability. – Basj Apr 6 at 14:35
With help from these answers, I finally got reverse proxy for Node-RED running on a Raspberry Pi with Ubuntu Mate and Apache2 working, using this Apache2 site config:
<VirtualHost *:80>
ServerName nodered.domain.com
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:1880/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) http://localhost:1880/$1 [P,L]
</VirtualHost>
I also had to enable modules like this:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
In addition to the main answer: if you have more than one service on the same server that uses websockets, you might want to do this to separate them, by using a custom path (*):
Node server:
var io = require('socket.io')({ path: '/ws_website1'}).listen(server);
Client HTML:
<script src="/ws_website1/socket.io.js"></script>
...
<script>
var socket = io('', { path: '/ws_website1' });
...
Apache config:
RewriteEngine On
RewriteRule ^/website1(.*)$ http://localhost:3001$1 [P,L]
RewriteCond %{REQUEST_URI} ^/ws_website1 [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule ^(.*)$ ws://localhost:3001$1 [P,L]
RewriteCond %{REQUEST_URI} ^/ws_website1 [NC]
RewriteRule ^(.*)$ http://localhost:3001$1 [P,L]
(*) Note: using the default RewriteCond %{REQUEST_URI} ^/socket.io
would not be specific to a website, and websockets requests would be mixed up between different websites!
TODO:
Have Apache 2.4 installed (doesn't work with 2.2),
a2enmod proxy
anda2enmod proxy_wstunnel.load
Do this in the Apache config
just add two line in your file where 8080 is your tomcat running port<VirtualHost *:80> ProxyPass "/ws2/" "ws://localhost:8080/" ProxyPass "/wss2/" "wss://localhost:8080/" </VirtualHost *:80>
For "polling" transport.
Apache side:
<VirtualHost *:80>
ServerName mysite.com
DocumentRoot /my/path
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /my-connect-3001 http://127.0.0.1:3001/socket.io
ProxyPassReverse /my-connect-3001 http://127.0.0.1:3001/socket.io
</VirtualHost>
Client side:
var my_socket = new io.Manager(null, {
host: 'mysite.com',
path: '/my-connect-3001'
transports: ['polling'],
}).socket('/');
User this link for perfact solution for ws https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html
You have to just do below step..
Got to /etc/apache2/mods-available
Step...1
Enable mode proxy_wstunnel.load by using below command
$a2enmod proxy_wstunnel.load
Step...2
Goto /etc/apache2/sites-available
and add below line in your .conf file inside virtual host
ProxyPass "/ws2/" "ws://localhost:8080/"
ProxyPass "/wss2/" "wss://localhost:8080/"
Note : 8080 mean your that your tomcat running port because we want to connect "ws" where our War file putted in tomcat and tomcat serve apache for "ws". thank you
My Configuration
ws://localhost/ws2/ALLCAD-Unifiedcommunication-1.0/chatserver?userid=4 =Connected
-
Sorry I don't really understand (especially your last sentence). Can you improve formatting of the answer and add details for people who don't know all what you mention? – Basj Jun 28 '17 at 15:39
-
Your Answer
Not the answer you're looking for? Browse other questions tagged node.js apache proxy websocket socket.io or ask your own question.
asked |
3 years, 7 months ago |
viewed |
65,973 times |
active |
Linked
Related
Hot Network Questions
-
Factory reset halfway through filevault decryption?
-
How to talk to a one night stand about her potential breast lumps issues?
-
Problem of a slow thinker
-
What purpose does economic inequality (inequality in wealth) serve?
-
Was Officer Alex Murphy medically murdered?
-
Is it normal for actors to name their characters?
-
What is the fastest rover that has ever traveled in space?
-
Is it ethical to slightly improve upon someone's unpublished work posted in arxiv and publish before the original work?
-
How to use cryptograpy to assure data integrity?
-
Moments of area of random triangle inscribed in a circle
-
Cat meows for wet food in morning despite dry food being available
-
Why do we still need to know about the Rankine temperature scale?
-
Confusion with the meaning of a component tolerance in terms of accuracy and standard deviation
-
What are the effects of slicing the Earth in half with a particle beam?
-
Why do people prefer pandas to SQL?
-
Other candidates' address in "recipients" list in a mail
-
What is the rarest launch window?
-
How do I grep multiple patterns from a pipe
-
My seatmate farts like rotten eggs. What ought the cabin crew do?
-
Tuples by sequentially stepping through entries in list of lists
-
gdb in one command
-
23 Years Old, With No Debt. Invest into Rental Properties or 401K?
-
Why will a USB flash drive get so hot when plugged into a Windows computer?
-
What do you do when your message could be dangerous?
site design / logo © 2018 Stack Exchange Inc; user contributions licensed under cc by-sa 3.0 with attribution required. rev 2018.7.13.31025