WebSockets и прокси-сервер Apache: как настроить mod_proxy_wstunnel?
У меня есть:
-
Apache
(v2.4) на порту 80 моего сервера для www.domain1.com
, mod_proxy и mod_proxy_wstunnel включен
-
node.js + socket.io
на порт 3001 того же сервера.
Доступ к www.domain2.com
(с портом 80) перенаправляет на 2. благодаря описанному здесь методу. Я установил это в конфигурации Apache:
<VirtualHost *:80>
ServerName www.domain2.com
ProxyPass / http://localhost:3001/
ProxyPassReverse / http://localhost:3001/
ProxyPass / ws://localhost:3001/
ProxyPassReverse / ws://localhost:3001/
</VirtualHost>
Он работает для всего, кроме части websocket: ws://...
не передаются, как это должно прокси.
Когда я обращаюсь к странице на www.domain2.com
, у меня есть:
Impossible to connect ws://www.domain2.com/socket.io/?EIO=3&transport=websocket&sid=n30rqg9AEqZIk5c9AABN.
Вопрос: Как сделать прокси-сервер Apache и WebSockets?
Ответы
Ответ 1
Мне удалось это сделать, благодаря этой теме.
TODO:
1) Установили ли Apache 2.4 (не работает с 2.2) и выполните следующие действия:
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_wstunnel
2) Запустите nodejs
на порт 3001
3) Сделайте это в конфигурации Apache
<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>
Примечание. Если у вас более одного сервиса на том же сервере, который использует веб-узлы, вы можете сделать это, чтобы отделить их.
Ответ 2
Вместо фильтрации по URL-адресу вы также можете фильтровать по HTTP-заголовку. Эта конфигурация будет работать для любых веб-приложений, которые используют веб-узлы, также если они не используют 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>
Ответ 3
Может быть, будет полезно.
Просто все запросы отправляются через ws на node
<VirtualHost *:80>
ServerName www.domain2.com
<Location "/">
ProxyPass "ws://localhost:3001/"
</Location>
</VirtualHost>
Ответ 4
Начиная с Socket.IO 1.0 (май 2014 г.), все подключения начинаются с запроса HTTP-опроса (подробнее здесь). Это означает, что в дополнение к пересылке трафика WebSocket вам необходимо перенаправить любые HTTP-запросы transport=polling
.
В приведенном ниже решении необходимо перенаправить весь трафик сокета, не перенаправляя ни один другой трафик.
-
Включите следующие мотивы Apache2:
sudo a2enmod proxy rewrite proxy_http proxy_wstunnel
-
Используйте эти настройки в файле *.conf(например, /etc/apache2/sites-available/mysite.com.conf
). Я включил комментарии для объяснения каждой части:
<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>
-
Я включил дополнительный раздел для маршрутизации /node
трафика, который мне удобен, см. здесь для получения дополнительной информации.
Ответ 5
С помощью этих ответов я, наконец, получил обратный прокси-сервер для Node -RED, работающий на малине Pi с Ubuntu Mate и Apache2, используя эту конфигурацию сайта Apache2:
<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>
Мне также пришлось включить такие модули:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
Ответ 6
Для меня это работает после добавления только одной строки в httpd.conf, как показано ниже (жирная линия).
<VirtualHost *:80>
ServerName: xxxxx
#ProxyPassReverse is not needed
ProxyPass /log4j ws://localhost:4711/logs
<VirtualHost *:80>
Apache версия 2.4.6 для CentOS.
Ответ 7
Моя настройка:
- Apache 2.4.10 (работает на Debian)
- Node.js (версия 4.1.1) Приложение, работающее на порте 3000, которое принимает WebSockets по пути
/api/ws
Как уже упоминалось выше @Basj, убедитесь, что прокси a2enmod и ws_tunnel включены.
Это скриншот конфигурационного файла Apache, который решил мою проблему:
![Apache config]()
Соответствующая часть в виде текста:
<VirtualHost *:80>
ServerName *******
ServerAlias *******
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
<Location "/api/ws">
ProxyPass "ws://localhost:3000/api/ws"
</Location>
</VirtualHost>
Надеюсь, это поможет.
Ответ 8
Сделал следующее для весеннего приложения, работающего со статическим содержимым, отдыхом и содержимым websocket.
Apache используется в качестве конечной точки прокси и SSL для следующих URI:
- /app → статический контент
- /api → REST API
- /api/ws → websocket
Конфигурация Apache
<VirtualHost *:80>
ServerName xxx.xxx.xxx
ProxyRequests Off
ProxyVia Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
RewriteEngine On
# websocket
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule ^/api/ws/(.*) ws://localhost:8080/api/ws/$1 [P,L]
# rest
ProxyPass /api http://localhost:8080/api
ProxyPassReverse /api http://localhost:8080/api
# static content
ProxyPass /app http://localhost:8080/app
ProxyPassReverse /app http://localhost:8080/app
</VirtualHost>
Я использую ту же конфигурацию vHost для конфигурации SSL, нет необходимости менять что-либо, связанное с прокси.
Конфигурация пружины
server.use-forward-headers: true
Ответ 9
Для "опроса" транспорта.
сторона Apache:
<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>
Клиентская сторона:
var my_socket = new io.Manager(null, {
host: 'mysite.com',
path: '/my-connect-3001'
transports: ['polling'],
}).socket('/');
Ответ 10
В дополнение к основному ответу: если у вас есть более одной службы на том же сервере, который использует веб-узлы, вы можете сделать это, чтобы отделить их, используя настраиваемый путь (*):
Node сервер:
var io = require('socket.io')({ path: '/ws_website1'}).listen(server);
Клиент HTML:
<script src="/ws_website1/socket.io.js"></script>
...
<script>
var socket = io('', { path: '/ws_website1' });
...
Конфигурация Apache:
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]
(*) Примечание: использование по умолчанию RewriteCond %{REQUEST_URI} ^/socket.io
не будет специфично для веб-сайта, а запросы веб-камер будут перемешаны между различными веб-сайтами!
Ответ 11
Используйте эту ссылку для идеального решения для ws https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html.
Вы должны просто сделать ниже шаг..
Перейдите в /etc/apache2/mods-available
Шаг 1
Включите mode proxy_wstunnel.load
с помощью команды ниже
$a2enmod proxy_wstunnel.load
Шаг 2
Перейдите в /etc/apache2/sites-available
и добавьте строку ниже в вашем файле .conf внутри виртуального хоста
ProxyPass "/ws2/" "ws://localhost:8080/"
ProxyPass "/wss2/" "wss://localhost:8080/"
Примечание: 8080 означают, что ваш, что ваш кот работает порт, потому что мы хотим, чтобы подключить ws
, где наш файл война гнал в коте и коте служит апачу для ws
. благодарю вас
Моя конфигурация
ws://localhost/ws2/ALLCAD-Unifiedcommunication-1.0/chatserver?userid=4 =Connected
Ответ 12
TODO:
-
Установлен ли Apache 2.4 (не работает с 2.2), a2enmod proxy
и a2enmod proxy_wstunnel.load
-
Сделайте это в конфигурации Apache
просто добавьте две строки в свой файл, где 8080 - ваш порт для работы с tomcat
<VirtualHost *:80>
ProxyPass "/ws2/" "ws://localhost:8080/"
ProxyPass "/wss2/" "wss://localhost:8080/"
</VirtualHost *:80>