Express and WebSocket listening on the same port

后端 未结 2 919
半阙折子戏
半阙折子戏 2020-12-13 06:40

I have an app.js which is used to trigger two events when some POST data are received:

  1. Insert POST data into a database
  2. Send a message to a client us
相关标签:
2条回答
  • 2020-12-13 06:50

    Based on your code and comments, here's a super simple example of how it would work together.

    First, the http-server.js - a typical express app, except that we do not start the server with app.listen():

    'use strict';
    
    let fs = require('fs');
    let express = require('express');
    let app = express();
    let bodyParser = require('body-parser');
    
    app.use(bodyParser.json());
    
    // Let's create the regular HTTP request and response
    app.get('/', function(req, res) {
    
      console.log('Get index');
      fs.createReadStream('./index.html')
      .pipe(res);
    });
    
    app.post('/', function(req, res) {
    
      let message = req.body.message;
      console.log('Regular POST message: ', message);
      return res.json({
    
        answer: 42
      });
    });
    
    module.exports = app;
    

    Now, the ws-server.js example, where we create the WSS server from a node native http.createServer(). Now, note that this is where we import the app, and give this native http.createServer the app instance to use.

    Start the app with PORT=8080 node ws-server.js :

    (Note you're launching the second, socket related, file (ws-server) not the first, http related, file (http-server).)

    'use strict';
    
    let WSServer = require('ws').Server;
    let server = require('http').createServer();
    let app = require('./http-server');
    
    // Create web socket server on top of a regular http server
    let wss = new WSServer({
    
      server: server
    });
    
    // Also mount the app here
    server.on('request', app);
    
    wss.on('connection', function connection(ws) {
     
      ws.on('message', function incoming(message) {
        
        console.log(`received: ${message}`);
        
        ws.send(JSON.stringify({
    
          answer: 42
        }));
      });
    });
    
    
    server.listen(process.env.PORT, function() {
    
      console.log(`http/ws server listening on ${process.env.PORT}`);
    });
    

    Finally, this sample index.html will work by creating both a POST and a Socket "request" and display the response:

    <html>
    <head>
      <title>WS example</title>
    </head>
    
    <body>
      <h2>Socket message response: </h2>
      <pre id="response"></pre>
      <hr/>
      <h2>POST message response: </h2>
      <pre id="post-response"></pre>
      <script>
    
      // Extremely simplified here, no error handling or anything
    document.body.onload = function() {
    
        'use strict';
    
      // First the socket requesta
      function socketExample() {
        console.log('Creating socket');
        let socket = new WebSocket('ws://localhost:8080/');
        socket.onopen = function() {
    
          console.log('Socket open.');
          socket.send(JSON.stringify({message: 'What is the meaning of life, the universe and everything?'}));
          console.log('Message sent.')
        };
        socket.onmessage = function(message) {
    
          console.log('Socket server message', message);
          let data = JSON.parse(message.data);
          document.getElementById('response').innerHTML = JSON.stringify(data, null, 2);
        };
      }
    
      // Now the simple POST demo
      function postExample() {
    
        console.log('Creating regular POST message');
      
        fetch('/', {  
          method: 'post',  
          headers: {  
            "Content-type": "application/json"  
          },  
          body: JSON.stringify({message: 'What is the meaning of post-life, the universe and everything?'})  
        })
        .then(response => response.json())  
        .then(function (data) {  
        
          console.log('POST response:', data);
          document.getElementById('post-response').innerHTML = JSON.stringify(data, null, 2);   
        })  
        .catch(function (error) {  
          console.log('Request failed', error);  
        });   
      }
    
      // Call them both;
    
      socketExample();
      postExample();
    }
      </script>
    </body>
    </html>
    

    Note you'll need a quite recent browser, one that has both WebSocket and fetch APIs for this client side part, but it's irrelevant anyway, it just gives you the gist of it.

    0 讨论(0)
  • 2020-12-13 07:11

    http and ws on the same port 80, "Amazing Zlatko Method™."

    You'll have a file, say main.js, with

     var app = express()
    

    and many lines of express code.

    It is perfectly OK to have as much middleware as you want in the usual way with no changes.

    var app = express()
    app.use(session(session_options))
    app.use(passport.initialize())
    app.use(passport.session())
    app.use('/static', express.static('static'))
    // etc etc
    app.get ...
    app.get ...
    app.post ...
    app.post ...
    

    Normally at the end of that file you would

     app.listen(80, (err) => { ... })
    

    Delete that.

     //app.listen(80, (err) => { ... })
    

    No other changes in the express app file.

    In your websocket file, say multiplayer.js, you would normally have

    const WebSocket = require('ws');
    const wss = new WebSocket.Server({
        port: 9999,
        perMessageDeflate: false
    })
    

    In fact, change to

    const WebSocket = require('ws');
    /*const wss = new WebSocket.Server({
        port: 2828,
        perMessageDeflate: false
    });*/
    let WSServer = WebSocket.Server;
    let server = require('http').createServer();
    let app = require('./main'); // note, that's your main.js file above
    let wss = new WSServer({
      server: server,
      perMessageDeflate: false
    })
    server.on('request', app);
    

    And at the end of that file

    server.listen(80, function() {
        console.log(`Amazing Zlatko Method™ combo server on 80`);
    });
    

    Note! - launch the 'multiplayer.js' file (not 'main.js').

    It works perfectly. Amazing stuff.

    0 讨论(0)
提交回复
热议问题