developer tip

WebSockets 및 Apache 프록시 : mod_proxy_wstunnel을 구성하는 방법?

optionbox 2020. 10. 13. 07:42
반응형

WebSockets 및 Apache 프록시 : mod_proxy_wstunnel을 구성하는 방법?


나는 가지고있다 :

  1. Apache내 서버의 포트 80 (V2.4) www.domain1.com와, mod_proxy를 하고 mod_proxy_wstunnel이 가능

  2. 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 프록시를 WebSocket으로 만드는 방법은 무엇입니까?


나는 이 주제 덕분에 마침내 그것을 할 수 있었다 .

할 것:

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>

참고 : 웹 소켓을 사용하는 동일한 서버에 둘 이상의 서비스가있는 경우 이를 분리하기 위해이 작업수행 할 수 있습니다.


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>

유용 할 수 있습니다. 모든 쿼리는 ws를 통해 노드로 전송됩니다.

<VirtualHost *:80>
  ServerName www.domain2.com

  <Location "/">
    ProxyPass "ws://localhost:3001/"
  </Location>
</VirtualHost>

Socket.IO 1.0 (2014 년 5 월)부터 모든 연결은 HTTP 폴링 요청으로 시작됩니다 (자세한 내용은 여기 ). 즉, WebSocket 트래픽을 전달하는 것 외에도 transport=pollingHTTP 요청 을 전달해야 합니다.

아래 솔루션은 다른 트래픽을 리디렉션하지 않고 모든 소켓 트래픽을 올바르게 리디렉션해야합니다.

  1. 다음 Apache2 모드를 활성화합니다.

    sudo a2enmod proxy rewrite proxy_http proxy_wstunnel
    
  2. * .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>
    
  3. /node편리한 트래픽 라우팅을위한 추가 섹션을 포함했습니다 . 자세한 내용은 여기참조 하십시오 .


이 답변의 도움으로 마침내이 Apache2 사이트 구성을 사용하여 Ubuntu Mate 및 Apache2가 작동하는 Raspberry Pi에서 실행되는 Node-RED에 대한 역방향 프록시를 얻었습니다.

<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

나를 위해 아래 (굵은 줄)와 같이 httpd.conf에 한 줄만 추가하면 작동합니다 .


<VirtualHost *:80>
    ServerName: xxxxx

    #ProxyPassReverse is not needed
    ProxyPass /log4j ws://localhost:4711/logs
<VirtualHost *:80>

CentOS에서 Apache 버전은 2.4.6입니다.


내 설정 :

  • Apache 2.4.10 (Debian에서 실행)
  • Node.js (버전 4.1.1) 경로에서 WebSocket을 허용하는 포트 3000에서 실행되는 앱 /api/ws

@Basj가 위에서 언급했듯이 a2enmod 프록시와 ws_tunnel이 활성화되어 있는지 확인하십시오.

이것은 내 문제를 해결 한 Apache 구성 파일의 스크린 샷입니다.

Apache 구성

텍스트로 관련 부분 :

<VirtualHost *:80>
  ServerName *******
  ServerAlias *******
  ProxyPass / http://localhost:3000/
  ProxyPassReverse / http://localhost:3000/

  <Location "/api/ws">
      ProxyPass "ws://localhost:3000/api/ws"
  </Location>
</VirtualHost>

도움이 되었기를 바랍니다.


정적, 휴식 및 웹 소켓 콘텐츠를 실행하는 스프링 애플리케이션에 대해 다음을 수행했습니다.

Apache는 다음 URI에 대해 프록시 및 SSL 끝점으로 사용됩니다.

  • / app → 정적 콘텐츠
  • / api → REST API
  • / api / ws → 웹 소켓

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>

SSL 구성에 동일한 vHost 구성을 사용하므로 관련 프록시를 변경할 필요가 없습니다.

봄 구성

server.use-forward-headers: true

"폴링"전송 용.

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('/');

기본 답변 외에도 웹 소켓을 사용하는 동일한 서버에 둘 이상의 서비스가있는 경우 사용자 지정 경로 (*)를 사용하여이를 분리하기 위해 이렇게 할 수 있습니다 .

노드 서버 :

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]

(*) 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:

  1. Have Apache 2.4 installed (doesn't work with 2.2), a2enmod proxy and a2enmod proxy_wstunnel.load

  2. 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>
    

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..

Go to /etc/apache2/mods-available

Step...1

Enable mode proxy_wstunnel.load by using below command

$a2enmod proxy_wstunnel.load

Step...2

Go to /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

참고 URL : https://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel

반응형