Socket.io, HTTPS et Proxy

69895
,

Bonjour à tous,

Je suis en train de mettre une application NodeJS en place sur mon serveur. Utilisant la technologie WebRTC, je suis contraint d'utiliser le protocole HTTPS (j'ai donc mis un certificat en place avec Let's encrypt), mais comme je ne veux pas passer par un autre port que le 80 et le 443, j'ai mis en place un ProxyPass avec Apache. Sauf que je suis un peu perdu avec Apache, les différents ports et les protocoles utilisés.

Au final, quand j'essaie d'exécuter mon code, socket.io n'arrive pas à se connecter à l'URL wss://monserver.truc/socket.io/…

Voici mes bouts de code :

app.js

var express = require('express'),
app = express(),
httpapp = express(),
fs = require('fs'),
server = require('http').createServer(app),
io = require('socket.io').listen(server);

app.get('/', function(request, response) {
        fs.readFile('./index.html', function(err, html) {
                response.writeHeader(200, {"Content-Type": "text/html"});
                response.write(html);
                response.end();
        });
});

io.sockets.on('connection', function(socket) {
        socket.on('buffer', function(data) {
                socket.broadcast.emit('buffer', data);
        });
});

server.listen(9782);

index.html

<!DOCTYPE html><html><head>
        <meta charset="UTF-8">
        <title>LIVE test</title>
</head><body>

        <script src="/socket.io/socket.io.js"></script>

        <script>
        (function main(){

        var socket = io.connect('https://monserveur.truc/', {secure: true, port: 443});

        navigator._getUserMedia = (   navigator.getUserMedia
           || navigator.webkitGetUserMedia
           || navigator.mozGetUserMedia
           || navigator.msGetUserMedia);

        window.AudioContext = window.AudioContext || window.webkitAudioContext;
        var audioContext = new AudioContext();

        function gotStream(stream) {
                var mediaStreamSource = audioContext.createMediaStreamSource(stream);
                // mediaStreamSource.connect(audioContext.destination);
                var scriptNode = audioContext.createScriptProcessor(4096, 1, 1);
                scriptNode.onaudioprocess = function(audioProcessingEvent) {
                        var inputBuffer = audioProcessingEvent.inputBuffer;
                        socket.emit('buffer', {
                                left: inputBuffer.getChannelData(0),
                                right: inputBuffer.getChannelData(1)
                        });
                };
                mediaStreamSource.connect(scriptNode);
        }

        navigator._getUserMedia({audio: true}, gotStream, function error() {});

        var audio = new Audio();

        var bufLeft = [], bufRight = [];

        var listener = audioContext.createScriptProcessor(4096, 1, 1);
        listener.onaudioprocess = function(audioProcessingEvent) {
                var outputBuffer = audioProcessingEvent.outputBuffer;
                var leftOut = outputBuffer.getChannelData(0);
                var rightOut = outputBuffer.getChannelData(1);
                if (bufLeft.length > 0) {
                        leftOut = bufLeft.splice(0, 1);
                        rightOut = bufRight.splice(0, 1);
                }
        };

        socket.on('buffer', function(data) {
                bufLeft.push(data.left);
                bufRight.push(data.right);
        });

        })();
        </script>
</body></html>

Ma conf Apache

<VirtualHost *:80 *:443>
        ServerName monserveur.truc
        SSLEngine on
        SSLProxyEngine on
        SSLProxyVerify none
        SSLProxyCheckPeerCN off
        SSLProxyCheckPeerName off
        SSLProxyCheckPeerExpire off
        SSLCertificateFile      /etc/letsencrypt/live/monserveur.truc/cert.pem
        SSLCertificateKeyFile   /etc/letsencrypt/live/monserveur.truc/privkey.pem
        SSLCertificateChainFile /etc/letsencrypt/live/monserveur.truc/fullchain.pem

        ProxyRequests off

        <Proxy *>
            Order deny,allow
            Allow from all
        </Proxy>
        ProxyPass /socket.io/1/websocket ws://127.0.0.1:9782/socket.io/1/websocket
        ProxyPassReverse /socket.io/1/websocket ws://127.0.0.1:9782/socket.io/1/websocket

        ProxyPass /socket.io/ http://127.0.0.1:9782/socket.io/
        ProxyPassReverse /socket.io/ http://127.0.0.1:9782/socket.io/

        ProxyPass / http://127.0.0.1:9782/
        ProxyPassReverse / http://127.0.0.1:9782/
</VirtualHost>

Merci pour votre aide :)

Christopher.

3 Réponse

17162
,

Bonsoir.
Tu n'aurais pas des erreurs dans ta configuration apache, comme par exemple :

ProxyPass /socket.io/1/websocket ws://127.0.0.1:9782/socket.io/1/websocket
ProxyPassReverse /socket.io/1/websocket ws://127.0.0.1:9782/socket.io/1/websocket

Tu dis vouloir accéder à wss://, mais dans ta configuration, tu as ws://.

69895
,

Merci pour ta réponse :)
Malheureusement ça ne fonctionne pas mieux. D'autant plus que le HTTPS se trouve au niveau d'Apache et non de NodeJS, donc en fait, ce que je voudrais parvenir à faire, c'est que le protocole wss:// soit redirigié vers ws:// en quelque sorte.

EDIT Petite précision supplémentaire, voici l'erreur que me remonte Chrome : WebSocket connection to 'wss://monserveur.fr/socket.io/?EIO=3&transport=websocket&sid=A9AioamsiPz-h0pqAAAA' failed: Error during WebSocket handshake: Unexpected response code: 400

Default
,

peut etre un peut plus de reponse sur ce lien je suis tombé sur ca en cherchant un peut ton erreur socket