Socket.io с прокси Apache (в соединении отказано) - PullRequest
0 голосов
/ 07 августа 2020

Я реализовал Socket.io на сервере node.js и SSL. Сначала я столкнулся с ошибкой подтверждения SSL, которую я успешно разрешил .

Я не открываю порт node.js напрямую для inte rnet, и все соединения сокетов проксируются через publi c Apache HTTPS-сервер.

Проблема в том, что при попытке подключиться к сокету браузер возвращает следующую ошибку:

WebSocket connection to 'wss://domain.com:4923/socket.io/?EIO=3&transport=websocket' failed: Connection closed before receiving a handshake response

My Apache виртуальный хост это:

<VirtualHost  *:443>
        ...

        SSLEngine On
        SSLProxyEngine On

        SSLCertificateFile /etc/letsencrypt/live/domain1.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/domain1.com/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf  

        SSLProxyCheckPeerName false    

        # Handle wss proxy connections
        RewriteEngine On
        RewriteCond %{REQUEST_URI}  ^/socket.io             [NC]
        RewriteCond %{QUERY_STRING} transport=websocket     [NC]
        RewriteRule /(.*)           ws://localhost:4923/$1 [P,L]

        # Autogenerated ProxyPass
        ProxyPass        /socket.io http://localhost:4923/socket
        ProxyPassReverse /socket.io http://localhost:4923/socket
        
        ...
</VirtualHost>

Тогда реализация сервера node.js следующая:

const port = 4923;

const fs = require('fs');

var options = {
    key: fs.readFileSync('/etc/ssl/private/vunkers.com.key'),
    cert: fs.readFileSync('/etc/ssl/certs/vunkers.com.crt'),
};

var express = require('express');
var app = express();
app.set("trust proxy", '127.0.0.1');
app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Headers", "Content-Type");
    res.header("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
    res.header("Access-Control-Allow-Credentials", "true");
    next();
});

var server = require('https').createServer(options, app);
var io = require('socket.io')(server, {
    path: '/socket',
    origins: '*:*'
});
server.listen(port);

io.httpServer.on('listening', function () {
    console.log("Listening on", port);
});

io.on('connection', (socket) => {
    console.log("New socket connection: " + socket.id);

    socket.on('login-request', (username, password) => {
        console.log("Login request: ");
        console.log(" - Username: " + username);
        console.log(" - Password: " + password);
    });

});

Наконец, мой клиент сокета таков:

...
const websocketOptions = {
        server : {
                protocol : 'https://',
                host     : 'domain1.com',
                port     : 443,
                endpoint : '/socket.io'
        }
};

function createConnection() {
        console.log("Creating websocket connection!");
        socket = io.connect(websocketOptions.server.protocol
                        + websocketOptions.server.host
                        + ':'
                        + websocketOptions.server.port
                        + websocketOptions.server.endpoint,
                        {transports: ['websocket', 'polling', 'flashsocket']});
}

function onWindowLoad() {
        createConnection();
}

window.onload = onWindowLoad;

У меня есть застрял в этом, и я хотел бы знать, что мне здесь не хватает.

Обновление

Я решил текущую ошибку, добавив файл SSL CA на виртуальный хост:

SSLCertificateChainFile /etc/letsencrypt/live/domain1.com/cert.ca.pem

Но теперь у меня ошибка отказа в соединении:

WebSocket connection to 'wss://domain.com:4923/socket.io/?EIO=3&transport=websocket' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
...