Hi.
I'm trying to connect a client websocket to an express server + socket.io. The server is HTTPS (self signed certificate — even if I know it's not supposed to work everywhere).
Here is how I create the server :
...
const app = express();
const server = https.createServer({
key : fs.readFileSync(key),
cert : fs.readFileSync(cert),
ca : fs.readFileSync(ca),
requestCert : true,
rejectUnauthorized: false
}, app);
app.locals.server = server;
server.listen(config.port, () => ...);
app.locals.io = socketio(app.locals.server, {
transports: ['websocket']
});
app.locals.io.on('connection', socket => {
...
});
Here is how my test looks like :
import io from 'socket.io-client';
describe('...', () => {
it('...', done => {
// Also tried with https, ws
let client = io.connect('wss://localhost:3006/', {
transports : ['websocket'],
secure : true, // Tried this or not
rejectUnauthorized: false, // Tried this or not
verify : false // Tried this or not
});
client.on('connect', () => done());
client.on('connect_error', err => {
console.log(err);
});
});
});
I disabled HTTP polling willingly (as it was interfering with my REST API
Edit :
The error is :
{ [Error: websocket error]
type: 'TransportError',
description:
{ [Error: socket hang up]
code: 'ECONNRESET',
type: 'error',
target:
WebSocket {
domain: null,
_events: [Object],
_eventsCount: 4,
_maxListeners: undefined,
_socket: null,
_ultron: null,
_closeReceived: false,
bytesReceived: 0,
readyState: 0,
supports: [Object],
extensions: {},
_isServer: false,
url: 'wss://localhost:3006/socket.io/?EIO=3&transport=websocket',
protocolVersion: 13,
binaryType: 'buffer' } } }
Thanks :)
The RejectUnauthorized param must be set on the https agent.
This snippet works great for a self-signed https server :
// server.js
import express from 'express';
import https from 'https';
import sio from 'socket.io';
import fs from 'fs';
const key = fs.readFileSync('./ssl/test/server.key');
const cert = fs.readFileSync('./ssl/test/server.crt');
const ca = fs.readFileSync('./ssl/test/ca.crt');
const opts = { key, cert, ca };
const app = express();
const server = https.createServer(opts, app);
const io = sio.listen(server);
server.listen(3006);
io.on('connection', socket => {
console.log('[OK] New connection');
});
For the client :
// client.js
import io from 'socket.io-client';
import https from 'https';
https.globalAgent.options.rejectUnauthorized = false;
const socket = io.connect('https://localhost:3006/', { agent: https.globalAgent });
socket.on('connect', function() {
console.log('[OK] Client connected');
});
Hope this helps :rocket:
@PymZoR This fixes my problem thanks :+1:
My client is in javascript in a html page. in that case will below code work?
the client.js which you are using is running in node js or from some html page ?
// client.js
import io from 'socket.io-client';
import https from 'https';
https.globalAgent.options.rejectUnauthorized = false;
const socket = io.connect('https://localhost:3006/', { agent: https.globalAgent });
socket.on('connect', function() {
console.log('[OK] Client connected');
});
@pmidalwan in a browser, you'll have to go to 'https://localhost:3006/
and authorize the domain to proceed. Example on Chrome:
In a Node.js environment, you can load the ca
for the client too:
const socket = require('socket.io-client')('https://localhost:3000', {
ca: fs.readFileSync('/path/to/cert.pem')
});
Please see https://github.com/socketio/socket.io-fiddle/tree/ssl-example for a complete example.
@darrachequesne
Thanks for your reply.
I am getting error in
const socket = require('socket.io-client')('https://localhost:3000', {
ca: fs.readFileSync('/path/to/cert.pem')
});
Error:
/usr/lib/node_modules/npm/client.js:5
e_modules/npm/node_modules/socket.io/node_modules/socket.io-client')('https://
^
TypeError: object is not a function
at Object.
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
Actually I am using old version of socket.io (0.8.7) due to some limitation I can not use latest version of node.
Do you have any idea how to resolve this ?
@darrachequesne
Hi... I modifyed the code as below and it compiled for me.
var fs = require('fs');
var io =require('/usr/lib/node_modules/npm/node_modules/socket.io/node_modules/socket.io-client');
var https= require('https');
const socket = io.connect('https://localhost:3000/', {rejectUnauthorized: true,
ca: fs.readFileSync('/mnt/readerconfig/ssl/server.crt')
});
socket.on('connect', function() {
console.log('[OK] Client connected');
});
socket.on('error', function(err) {
console.log('[OK] Client connected'+err);
});
but the issue is again same . With self signed certificate it returned with below error :
root@FX9600EF95C5:/usr/lib/node_modules/npm# node client.js
[OK] Client connectedError: self signed certificate
at Error (native)
at TLSSocket.
at TLSSocket.emit (events.js:104:17)
at TLSSocket._finishInit (_tls_wrap.js:467:8)
Most helpful comment
The RejectUnauthorized param must be set on the https agent.
This snippet works great for a self-signed https server :
For the client :
Hope this helps :rocket: