Partage
  • Partager sur Facebook
  • Partager sur Twitter

Apache 2.4 et ProxyPass Socket.IO (node.js)

Comment proxyfier uniquement du socket.io ?

Sujet résolu
    18 novembre 2017 à 0:26:03

    Bonjour, 
    Disclaimer : Je ne savais pas ou poster ce topic entre le forum Javascript où ça peut parler de Node.js ou le forum Linux où ça peut parler de config Apache et serveur. Comme je pense que c'est un problème côité Apache, j'ai choisi de poster ici, si jamais je me suis trompé, je m'en excuse, j'invite un modo à déplacer ce topic à la bonne place. ^^
    Je viens quérir auprès de vous de l'aide concernant de la configuration de vhost sur un Apache 2.4 (sur un serveur Debian), plus précisément pour utiliser le mod_proxy pour proxyfier du socket.io:pirate:
    Ca peut paraitre barbare vu comme ça, et je ne sais pas du tout si ce que je veux rentre dans le cadre de best practice... Dans le doute, je vais vous expliquer mon besoin, voir s'il est possible de faire autrement. :-°
    Je possède un jeu codé en PHP, celui-ci fonctionne à merveille, il est hébergé, tout roule. Sur celui-ci, j'aimerais à l'avenir accoler une nouvelle page qui soit interactive et mis à jour en direct selon les actions des joueurs, et je me suis donc orienté naturellement vers Node.JS et Socket.IO, ne connaissant pas d'autres solutions.


    Pourquoi proxyfier ? Car L'utilisateur de Socket.io requiert un port différent de celui d'Apache, et j'aimerais que le futur site reste accessible uniquement par le port 80 (et 443 pour l'https). J'aurais donc mon Apache sur le port 80 qui sert mon HTML et mon PHP, et derrière, mon serveur Node qui s'occupera de la partie Socket.IO. 
    Je ne peux bien sûr pas transcrire mon site actuel complètement en node.js pour abandonner apache et coller mon node.js sur le port 80 seul. ^^ 
    Dans l'idéal, ce que j'avais imaginé :
    • 1. Quand l'utilisateur arrive sur la page, c'est bien le serveur Apache (et PHP) qui servira la page.
    • 2. En JS, l'utilisateur va récupérer son Socket (Donc là, il y a nécessité de proxyfier pour atteindre le serveur node qui va servir le socket). 
    • 3. La page est interactive est mise à jour en JS par le serveur node grâce aux sockets et selon les actions des autres utilisateurs sur cette même page. 
    Idem ici, je vous invite à me dire si je fais fausse route sur le modus operandi que je propose, je suis preneur de toutes les solutions :D 
    Sur le papier, ça marche, j'ai testé en local, une page HTML servi par mon Wampserver, je me connecte à un socket en JS au serveur node et roulez jeunesse ! :soleil:
    Ca se complique quand je veux tester sur mon vrai serveur en conditions réelles, avec un Apache et un serveur Node proxifié. 
    J'ai donc mon Apache en 80 et mon Node sur le port 1338 (oui, le 1337 était déjà pris :ninja: ).
    Je configure donc mon Vhost comme suit (trouvé sur d'autres threads d'Internet), après avoir activé proxy, proxy_html tout ce qui était nécessaire :
    <VirtualHost *:80>
        ServerName domain.tld
        DocumentRoot /home/folder/www
        <Directory /home/folder/www>
            Options FollowSymLinks MultiViews
            AllowOverride All
            Require all granted
        </Directory>
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        LogLevel warn
    
      RewriteEngine On
      RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
      #RewriteCond %{QUERY_STRING} transport=websocket    [NC]
      RewriteRule /(.*)           ws://localhost:1338/$1 [P,L]
    
      ProxyPass / http://localhost:1338/
      ProxyPassReverse / http://localhost:1338/
    </VirtualHost>
    Bien sûr, mon serveur node est bien sur : 
    httpServer.listen(1338);
    var io = require("socket.io").listen(httpServer);
    
    io.sockets.on("connection", function(socket){
    ...
    }
    Et côté client, il y a nécessité de charger le JS client de socket.IO servi par le serveur node : 
    <script src="/socket.io/socket.io.js"></script>
    Ainsi que se connecter à un socket : 
    var socket = io.connect("http://domain.tld/socket.io");
    Or, en l'état actuel, j'ai beau bidouillé ma config Apache, et avoir farfouillé à travers les Interweb pendant des heures, je n'arrive pas à proxyfier correctement mon serveur node, il reste inaccessible. J'ai pas du comprendre un truc, et je suis sûr que c'est tout con. ^^'
    Si jamais vous voulez m'aider, je vous en serez infiniment reconnaissant :ange:
    EDIT : 

    Bon, j'ai trouvé une config qui me fait avancer un petit peu : 

    RewriteEngine On
    RewriteRule /socket.io/1/websocket/ - [R=200,L]
    ProxyPass /socket.io/socket.io.js http://127.0.0.1:1338/socket.io/socket.io.js
    ProxyPassReverse /socket.io/socket.io.js http://127.0.0.1:1338/socket.io/socket.io.js
    ProxyPass /socket.io/1/websocket/ ws://127.0.0.1:1338/socket.io/1/websocket/
    ProxyPassReverse /socket.io/1/websocket/ ws://127.0.0.1:1338/socket.io/1/websocket/
    ProxyPass /socket.io/1/ http://127.0.0.1:1338/socket.io/1/
    ProxyPassReverse /socket.io/1/ http://127.0.0.1:1338/socket.io/1/

    J'arrive maintenant à atteindre /socket.io/socket.io.js, par contre, les websockets tombent toujours en 404... 

    GET http://domain.tld/socket.io/?EIO=3&transport=polling&t=L_F7frg 404 (Not Found)
    ...

    Ce qui donne niveau Apache : 

    [Sat Nov 18 13:31:09.431794 2017] [proxy:warn] [pid 22356] [client xx.xx.xx.xx:52436] AH01144: No protocol handler was valid for the URL /socket.io/. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule., referer: http://domain.tld/

    Need Help :/

    -
    Edité par Harmo801 18 novembre 2017 à 13:42:55

    • Partager sur Facebook
    • Partager sur Twitter
      19 novembre 2017 à 0:38:16

      Hello, 

      J'ai fini par trouver ma solution tout à l'heure dans l'après-midi. 

      J'ai d'abord créé un vhost node.domain.tld pour le dissocier du domaine principal. Ca a facilité le fait de proxyfier puisque je n'avais plus de règle spécifique à mettre en place, c'est tout le sous-domaine qu'il faut proxyfier jusqu'au serveur node. 

      Ca marchait déjà un peu mieux, sauf que le websocket foirait au niveau de l'handshake et repassait en "long-polling", même si ça ne changeait pas grand chose, c'était quand même dommage. 

      J'ai finalement trouvé une solution toute faite par fuatsengul sur github via ce lien : https://github.com/meteor/meteor/issues/3339 

      The error page, SSL and rewrites(forcing ssl) are extra, you don't have to use them.
      Also, my apache on 2.4.10 and proxy_wstunnel has enabled.
      
      <VirtualHost *:443>
           ServerName mysite.com
           ServerAlias www.mysite.com
      
           SSLEngine on
           SSLProxyEngine On
           ProxyRequests Off
      
           SSLCertificateFile /etc/apache2/ssl/mysite.com.crt
           SSLCertificateKeyFile /etc/apache2/ssl/mysite.com.key
           SSLCertificateChainFile /etc/apache2/ssl/ca.cer
      
           DocumentRoot /var/www/errorPages
      
           ErrorDocument 503 /503.html
           ProxyPass /503.html !
      
           ProxyPass / http://localhost:3999/
           ProxyPassReverse / http://localhost:3999/
      
      
      RewriteEngine on
      RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
      RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
      RewriteRule .* ws://localhost:3999%{REQUEST_URI} [P]
      
      
      </VirtualHost>

      Cette config fonctionne à merveille. 

      Je poste ma solution au cas ou quelqu'un d'autre passerait par là. 

      • Partager sur Facebook
      • Partager sur Twitter
        2 août 2018 à 22:30:50

        Hello,

        J'ai exactement la même problématique (mon site est sous HTTPS)

        J'ai modifie ma config apache mais j'ai des 404 wss://

        Une idée ?

        • Partager sur Facebook
        • Partager sur Twitter

        Apache 2.4 et ProxyPass Socket.IO (node.js)

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown