I created a nodejs server with https. There is no problem when making a GET request, but when connecting with another nodejs application that works with socket.io-client, I get the error 'WebSocket was closed before the connection was established'. What could be the reason?
server.js:
import https from 'https';
import fs from 'fs';
import { Server } from 'socket.io';
const options = {
key: fs.readFileSync('../certs/server-key.pem'),
cert: fs.readFileSync('../certs/server-crt.pem'),
ca: [
fs.readFileSync('../certs/client-ca-crt.pem')
],
requestCert: true,
rejectUnauthorized: false
};
const server = https.createServer(options);
const io = new Server(server, { serveClient: false });
io.sockets.on('connection', function (socket) {
console.log(socket.id);
});
server.listen({ port: 8443, host: 'localhost' }, () => {
console.log(server.address());
});
client.js:
import { io } from 'socket.io-client';
import fs from 'fs';
const socket = io('https://server.aaa.com:8443', {
hostname: 'server.aaa.com',
transports: ['websocket'],
key: fs.readFileSync('../certs/client-key.pem'),
cert: fs.readFileSync('../certs/client-crt.pem'),
ca: [
fs.readFileSync('../certs/server-ca-crt.pem')
],
rejectUnauthorized: false,
reconnection: false
});
socket.on('connect', () => {
console.log(socket.id);
});
socket.on("error", (err) => {
console.log(err);
});
socket.on("connect_error", (err) => {
console.log(err);
});
No problem with that:
const fs = require("fs");
const https = require("https");
const message = { msg: "Hello!" };
const req = https.request(
{
host: "server.aaa.com",
port: 8443,
key: fs.readFileSync(`../certs/client-key.pem`),
cert: fs.readFileSync(`../certs/client-crt.pem`),
ca: [
fs.readFileSync(`../certs/server-ca-crt.pem`)
],
path: "/",
method: "GET",
},
function(response) {
let rawData = "";
response.on("data", function(data) {
rawData = data;
});
response.on("end", function() {
if (rawData.length > 0) {
console.log(`Received message: ${rawData}`);
}
console.log(`TLS Connection closed!`);
req.end();
return;
});
}
);
req.on("socket", function(socket) {
socket.on("secureConnect", function() {
if (socket.authorized === false) {
console.log(`SOCKET AUTH FAILED ${socket.authorizationError}`);
}
console.log("TLS Connection established successfully!");
});
socket.setTimeout(10000);
socket.on("timeout", function() {
console.log("TLS Socket Timeout!");
req.end();
return;
});
});
req.on("error", function(err) {
console.log(`TLS Socket ERROR (${err})`);
req.end();
return;
});
req.write(JSON.stringify(message));
output:
TLS Connection established successfully!
Received message: OK!
TLS Connection closed!
CodePudding user response:
I finally found the solution to the problem.
I need to add the following code for socket.io to use the default socket.io path (/socket.io).
io.listen(server);
server.js
import https from 'https';
import fs from 'fs';
import { Server } from 'socket.io';
const options = {
key: fs.readFileSync('../certs/server-key.pem'),
cert: fs.readFileSync('../certs/server-crt.pem'),
ca: [
fs.readFileSync('../certs/client-ca-crt.pem')
],
requestCert: true,
rejectUnauthorized: false
};
const server = https.createServer(options);
const io = new Server(server);
io.listen(server);
io.on('connection', function (socket) {
console.log(socket.id);
});
server.listen({ port: 9443, host: 'localhost' }, () => {
console.log(server.address());
});
CodePudding user response:
Your server is listening on localhost, but the client is trying to connect to server.aaa.com. So you have to make the server listen on server.aaa.com
or 0.0.0.0
.