node.jsexpresswebsockethttpsexpress-ws

websockets not working with https.createServer


Our websockets are working under Http/express but when I move to https.createServer I cant get a socket connention.

FYI:The project is almost complete and we are in deep with express-ws, so we cont change the socket lib at this stage

Here is an example of my code:

import express from 'express';
import expressWs from 'express-ws'

const app = express();
const port = 443

expressWs(app);

app.ws('/api/websocket',socketApiLogic)
app.get('/',indexLogic)
app.use(express.static(path.join(__dirname, '../build/')));
app.use('*', express.static(path.join(__dirname, '../build/404.html')));


if (process.env.prod || process.env.NODE_ENV == 'prod') {
  const server = require('https').createServer({
                                    key: fs.readFileSync(path.resolve(__dirname,'../ssl/key.pem')),
                                    cert: fs.readFileSync(path.resolve(__dirname,'../ssl/cert.pem')),
                                  }, app)
  
  require('http').createServer(function (req, res) {
      res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url });
      res.end();
  }).listen(80);
  
  server.addListener('upgrade', (req, res, head) => console.log('UPGRADE:', req.url));
  server.on('error', (err) => console.error(err));
  
  server.listen(port, () => {
         console.log('= Prod mode = ' + port);
    });
  
} else {
  
  app.listen(port, () => {
        console.log('= Dev mode = ' + port);
 });

}

Thanks for any help


Solution

  • From the documentation You can pass the server as the 2nd argument.

    You code should be more like

    // imports & config
    
    import express from 'express';
    import expressWs from 'express-ws'
    
    const app = express();
    const port = 443
    const isProd = process.env.prod || process.env.NODE_ENV == 'prod'
    
    if (isProd) {
      startProd()
    } else {
      startLocal()
    }
    
    // SSL server
    function startProd(){
    
      setupPaths()
    
    // ~~~~~~~~~~~ SETUP YOUR SSL SERVER
    
      const server = require('https').createServer({
                                        key: fs.readFileSync(path.resolve(__dirname,'../ssl/key.pem')),
                                        cert: fs.readFileSync(path.resolve(__dirname,'../ssl/cert.pem')),
                                      }, app)
      
      require('http').createServer(function (req, res) {
          res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url });
          res.end();
      }).listen(80);
      
      server.addListener('upgrade', (req, res, head) => console.log('UPGRADE:', req.url));
      server.on('error', (err) => console.error(err));
      
      server.listen(port, () => {
             console.log('= Prod mode = ' + port);
        });
    
    // ~~~~~~~~~~~ USE YOUR SSL SERVER
    
      expressWs(app,server);
      app.ws('/api/websocket',socketApiLogic)
      catchAllPaths()
    }
    
    // localhost server
    function startLocal(){
    
      expressWs(app);
      app.ws('/api/websocket',socketApiLogic)
      setupPaths()
      catchAllPaths()
      app.listen(port, () => {
            console.log('= Server started = ' + port);
     });
    }
    
    // Add paths
    function setupPaths(){
    app.get('/',indexLogic)
    }
    function catchAllPaths(){
    app.use(express.static(path.join(__dirname, '../build/')));
    app.use('*', express.static(path.join(__dirname, '../build/404.html')));
    }