Search code examples
node.jsapachewebsockethttps

WebSocket Error in connection establishment: net::ERR_CONNECTION_CLOSED


I am getting this error when I attempt to establish a wss connection with my server:

WebSocket connection to 'wss://mydomain:3000/' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED

I currently have a apache2 virtual host configuration setup to listen for requests on port 443 and 80:

<VirtualHost *:80>
        ServerName otherdomainname.co.uk
        ServerAlias www.otherdomainname.co.uk

        RewriteEngine On
        RewriteRule ^/(.*)$ /app/$1 [l,PT]

        JkMount /* worker2

</VirtualHost>

<VirtualHost _default_:443>
        ServerName otherdomainname.co.uk
        ServerAlias www.otherdomainname.co.uk

        RewriteEngine On
        RewriteRule ^/(.*)$ /app/$1 [l,PT]

        SSLEngine On
        SSLCertificateFile /etc/apache2/ssl/apache.crt
        SSLCertificateKeyFile /etc/apache2/ssl/apache.key

        <Location />
        SSLRequireSSL On
        SSLVerifyClient optional
        SSLVerifyDepth 1
        SSLOptions +StdEnvVars +StrictRequire
        </Location>

        JkMount /* worker2

</VirtualHost>

As you can see it uses the JkMount to pass the request to Tomcat which serves the webpage correctly on both HTTP and HTTPS.

When I visit the site using the HTTP protocol on port 80 a WebSocket connection can be made using the ws protocol.

When I visit the site using the HTTPS protocol on port 443 the site is served correctly but no WebSocket connection is made using wss.

I am using the "ws" node.js module to provide the WebSocket server:

var WebSocketServer = require('ws').Server
  , wss = new WebSocketServer({ port: 3000 }),
  fs = require('fs');

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);

    ws.send(message);
  ws.send('something');
});

Why am I not able to successful connect to the WebSocket server using the wss protocol over https?


Solution

  • The problem was that I was not configure the WebSocket server for https/wss.

    Here is the secure version of my insecure WebSocket server using "ws" from node.js.

    var WebSocketServer = require('ws').Server,
      fs = require('fs');
    
    
    var cfg = {
            ssl: true,
            port: 3000,
            ssl_key: '/path/to/apache.key',
            ssl_cert: '/path/to/apache.crt'
        };
    
    var httpServ = ( cfg.ssl ) ? require('https') : require('http');
    
    var app      = null;
    
    var processRequest = function( req, res ) {
    
        res.writeHead(200);
        res.end("All glory to WebSockets!\n");
    };
    
    if ( cfg.ssl ) {
    
        app = httpServ.createServer({
    
            // providing server with  SSL key/cert
            key: fs.readFileSync( cfg.ssl_key ),
            cert: fs.readFileSync( cfg.ssl_cert )
    
        }, processRequest ).listen( cfg.port );
    
    } else {
    
        app = httpServ.createServer( processRequest ).listen( cfg.port );
    }
    
    var wss = new WebSocketServer( { server: app } );
    
    wss.on('connection', function connection(ws) {
      ws.on('message', function incoming(message) {
        console.log('received: %s', message);
    
        ws.send(message);
    
      });
    
      ws.send('something');
    });