WebSockets और Apache प्रॉक्सी: mod_proxy_wstunnel कैसे कॉन्फ़िगर करें?


98

मेरे पास है :

  1. Apache(v2.4) mod_proxy और mod_proxy_wstunnel सक्षम के www.domain1.comसाथ मेरे सर्वर के पोर्ट 80 पर

  2. node.js + socket.io उसी सर्वर के पोर्ट 3001 पर।

एक्सेस www.domain2.com(पोर्ट 80 के साथ) 2 पर रीडायरेक्ट करता हैयहाँ वर्णित विधि के लिए धन्यवाद । मैंने इसे अपाचे कॉन्फ़िगरेशन में सेट किया है:

<VirtualHost *:80>
    ServerName www.domain2.com
    ProxyPass / http://localhost:3001/
    ProxyPassReverse / http://localhost:3001/
    ProxyPass / ws://localhost:3001/
    ProxyPassReverse / ws://localhost:3001/
</VirtualHost>

यह वेबसोकेट भाग को छोड़कर सब कुछ के लिए काम करता है: ws://...प्रॉक्सी द्वारा इसे प्रसारित नहीं किया जाना चाहिए।

जब मैं पृष्ठ पर www.domain2.comपहुंचता हूं, तो मेरे पास है:

Impossible to connect ws://www.domain2.com/socket.io/?EIO=3&transport=websocket&sid=n30rqg9AEqZIk5c9AABN.

प्रश्न: कैसे अपाचे प्रॉक्सी के रूप में अच्छी तरह से WebSockets बनाने के लिए?

जवाबों:


160

मैं अंत में इसे करने में कामयाब रहा, इस विषय के लिए धन्यवाद ।

करने के लिए:

1) अपाचे 2.4 स्थापित है (2.2 के साथ काम नहीं करता है), और करें:

a2enmod proxy
a2enmod proxy_http
a2enmod proxy_wstunnel

2) nodejsपोर्ट 3001 पर चल रहा है

3) 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>

नोट: यदि आपके पास एक ही सर्वर पर एक से अधिक सेवा है जो वेबसोकेट का उपयोग करता है, तो आप उन्हें अलग करने के लिए ऐसा करना चाह सकते हैं ।


FWIW, अपाचे 2.4 सेंटोस 7.1 में इस बग में इसलिए है कि फिर से लिखना ws: // प्रोटोकॉल को मान्यता नहीं देगा, और सब्रेक्वेस्ट भेजने से पहले डोमेन को प्रस्तुत करता है। [R] edirect को [P] रॉक्सी फ्लैग को बदलकर आप खुद को परख सकते हैं।
Andor

3
मुझे अभी भी अपने ws: // मार्गों के लिए 502 ख़राब गेटवे मिलते हैं। Ubuntu 14.04 पर अपाचे 2.4 रनिंग
एलेक्स मूरो

1
यह काम करता है क्योंकि सभी HTTP ट्रैफ़िक को आगे भेजा जा रहा है, लेकिन यदि आप केवल अपने सॉकेट ट्रैफ़िक को फ़ॉरवर्ड करना चाहते हैं, तो कृपया ध्यान दें कि सॉकेट.io एक HTTP पोलिंग रिक्वेस्ट के साथ संचार शुरू करता है। अधिक जानकारी यहाँ
एरिक कोपामंस

4
443 wss से ws तक फॉरवर्ड कैसे करें? क्या फिर से लिखना बदलता है?
हर्नान एचे सेप

1
शर्त RewriteCond %{QUERY_STRING} transport=websocket [NC]ने मुझे सही ढंग से काम नहीं किया। RewriteCond %{HTTP:Upgrade} =websocket [NC]इसके बजाय उपयोग करने का सुझाव ।
मार्टिन

99

URL द्वारा फ़िल्टर करने के बजाय, आप HTTP शीर्ष लेख द्वारा फ़िल्टर भी कर सकते हैं। यह कॉन्फ़िगरेशन किसी भी वेब एप्लिकेशन के लिए काम करेगा जो वेबस्कैट का उपयोग करते हैं, भले ही वे सॉकेट का उपयोग नहीं कर रहे हों।

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

यह मेरे लिए ठीक काम कर रहा है, लेकिन मैं एक सबपैथ को समीप कर रहा हूं और मैंने पाया है कि ^ एंकर को जोड़ना महत्वपूर्ण है क्योंकि रेगेक्स एक विकल्प की तलाश में है। Eg RewriteRule ^ [^ /] * / foo /(.*) http: // $ {FOO_HOST} / $ 1 [P, L] (अन्यथा / बार / foo को भी उसी स्थान पर / foo के रूप में निर्देशित किया जाएगा)
स्टीव लिली

यह क्लाउड अलीबाबा क्लाउड पर सबसे अच्छा काम करता है। इसके अलावा, यह त्रुटि नेट को ठीक करेगा :: ERR_RESPONSE_HEADERS_TRUNCATED "आशा है कि कोई इसे उपयोगी
पाता है

सिग्नलआर का उपयोग करते हुए, मैं कह सकता हूं, यह मेरे लिए सबसे अच्छा काम करता है +1 धन्यवाद
वोजत मिराज

18

उपयोगी हो सकता है। बस सभी प्रश्नों को ws से नोड तक भेजते हैं

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

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

साभार @Sergey इससे मुझे तब मदद मिली जब मैंने रूट को दस्तावेज़ रूट करने के लिए सब कुछ रूट करने के बजाय केवल प्रत्यक्ष पथ का उपयोग किया। मैंने दिखाया है कि मैंने दूसरों के लाभ के लिए नीचे एक उत्तर में क्या किया है।
अनवारुल्लाह

यह उत्तर सरल वेब सॉकेट (नो सॉकेट.आईओ) के लिए काम करता है, इसलिए मेरे लिए यह बेहतर उत्तर है
टॉमस

बहुत बढ़िया! यह तुरंत मेरे लिए काम कर रहा था, जबकि अन्य पुन: लिखने और छद्म प्रयासों ने मेरी समस्या को हल नहीं किया।
Stephan

धन्यवाद!! बुनियादी उपयोग के मामले के लिए बिल्कुल सही, बस एक साधारण वेब सॉकेट का उपयोग कर ws: //
एंटोनिया ब्लेयर

16

सॉकेट.आईओ 1.0 (मई 2014) के अनुसार, सभी कनेक्शन एक HTTP पोलिंग रिक्वेस्ट ( यहाँ अधिक जानकारी ) से शुरू होते हैं। इसका मतलब है कि WebSocket ट्रैफ़िक को अग्रेषित करने के अलावा, आपको किसी भी transport=pollingHTTP अनुरोध को अग्रेषित करने की आवश्यकता है ।

नीचे दिए गए समाधान को सभी सॉकेट ट्रैफ़िक को सही ढंग से रीडायरेक्ट करना चाहिए, बिना किसी अन्य ट्रैफ़िक को रीडायरेक्ट किए।

  1. निम्नलिखित Apache2 mods सक्षम करें:

    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ट्रैफ़िक को रूट करने के लिए एक अतिरिक्त अनुभाग शामिल किया है जो मुझे उपयोगी लगता है, अधिक जानकारी के लिए यहां देखें ।


1
यह मेरे लिए पूरी तरह से काम करता है। ध्यान दें कि यदि आपके अनुरोध रूट के अलावा किसी URL पर आ रहे हैं, तो आप कर सकते हैं जैसेRewriteRule /path/(.*)
Rob Gwynn-Jones

8

इन उत्तरों की मदद से, मुझे अंततः अपाचे 2 साइट कॉन्फिगरेशन का उपयोग करके उबंटू मेट और अपाचे 2 के साथ रास्पबेरी पाई पर चलने वाले नोड-रेड के लिए रिवर्स प्रॉक्सी मिल गई:

<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

7

मेरे लिए यह httpd.conf में नीचे (बोल्ड लाइन) के रूप में केवल एक लाइन जोड़ने के बाद काम करता है ।


<VirtualHost *:80>
    ServerName: xxxxx

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

अपाचे संस्करण 2.4.6 सेंटोस पर है।


5

मेरा सेटअप:

  • Apache 2.4.10 (डेबियन से भागना)
  • Node.js (संस्करण 4.1.1) ऐप पोर्ट 3000 पर चल रहा है जो पथ पर WebSockets को स्वीकार करता है /api/ws

जैसा कि @Basj द्वारा ऊपर उल्लेख किया गया है, सुनिश्चित करें कि a2enmod प्रॉक्सी और ws_tunnel सक्षम हैं।

यह 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>

उम्मीद है की वो मदद करदे।


मुझे डिफ़ॉल्ट के बजाय एक पसंदीदा URL के साथ अपना ऐप सेट करने में समस्या हो रही है, क्या आप मेरी मदद करेंगे? (मैं एक वार्निश कैश सर्वर के शीर्ष पर बैठा हूं)
जोश

6
क्या आप स्क्रीनशॉट के बजाय कॉपी / पेस्ट कर सकते हैं? अग्रिम धन्यवाद, यह पठनीयता में सुधार करेगा।
बसज

3

क्या स्थैतिक, आराम और वेबसोकेट सामग्री चलाने वाले स्प्रिंग एप्लिकेशन के लिए निम्न कार्य किया गया था।

अपाचे का उपयोग प्रॉक्सी और एसएसएल समापन बिंदु के रूप में निम्न यूआरआई के लिए किया जाता है:

  • / एप्लिकेशन → स्थिर सामग्री
  • / एपीआई → रीस्ट एपीआई
  • / एपी / डब्ल्यूएस → वेबसोकेट

अपाचे विन्यास

<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 कॉन्फिगर का उपयोग करता हूं, इससे संबंधित किसी भी प्रॉक्सी को बदलने की कोई आवश्यकता नहीं है।

वसंत विन्यास

server.use-forward-headers: true

स्थानों को अलग करने के लिए स्थान टैग का उपयोग करें, अर्थात: <स्थान / ऐप> प्रॉक्सीपे लोकलहोस्ट: 8080 / ऐप ProxyPassReverse localhost: 8080 / ऐप </ स्थान>
CrazyMerlin

2

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

क्षमा करें, मुझे वास्तव में समझ में नहीं आया (विशेषकर आपका अंतिम वाक्य)। क्या आप उत्तर के प्रारूपण में सुधार कर सकते हैं और उन लोगों के लिए विवरण जोड़ सकते हैं जो आपके द्वारा उल्लिखित सभी को नहीं जानते हैं?
बसज

क्या है Tomcat @ अरविंदमधुकर?
बसज

1

"मतदान" परिवहन के लिए।

अपाचे पक्ष:

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

1

मुख्य उत्तर के अलावा: यदि आपके पास एक ही सर्वर पर एक से अधिक सेवा है जो वेबस्कैट का उपयोग करता है, तो आप कस्टम पथ (*) का उपयोग करके उन्हें अलग करने के लिए ऐसा करना चाह सकते हैं :

नोड सर्वर:

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' });
...

अपाचे विन्यास:

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करना एक वेबसाइट के लिए विशिष्ट नहीं होगा, और विभिन्न वेबसाइटों के बीच वेबस्कैट अनुरोधों को मिलाया जाएगा!


0

करने के लिए:

  1. Apache 2.4 स्थापित है (2.2 के साथ काम नहीं करता है), a2enmod proxyऔरa2enmod proxy_wstunnel.load

  2. अपाचे कॉन्फिगर
    में ऐसा करें अपनी फाइल में सिर्फ दो लाइन जोड़ें जहां 8080 में आपका टॉमकट रनिंग पोर्ट है

    <VirtualHost *:80>
    ProxyPass "/ws2/" "ws://localhost:8080/" 
    ProxyPass "/wss2/" "wss://localhost:8080/"
    
    </VirtualHost *:80>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.