Я реализовал 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