代码之家  ›  专栏  ›  技术社区  ›  Mornor

Express和WebSocket在同一端口上侦听

  •  47
  • Mornor  · 技术社区  · 10 年前

    我有一个应用程序。js,用于在接收到一些POST数据时触发两个事件:

    1. 将POST数据插入数据库
    2. 使用WebSocket向客户端发送消息

    这是 应用程序.js (仅重要行)

    var express = require('express');
    var bodyParser = require('body-parser');
    var server = require('./server');
    
    var app = express();
    var port = process.env.PORT || 3000;
    
    app.post('/server', server);
    
    app.listen(port, function(){
      console.log('Slack bot listening');
    });
    

    这是 服务器.js (仅重要行)

    var db = require('./DB');
    var WebSocketServer = require('ws').Server;
    
    var insertData = function(req, res){
    
        var wss = new WebSocketServer({server: server});
        console.log('WebSocketServer created');
        wss.on('connection', function(wss){
            wss.send(JSON.stringify('Socket open'));
        });
        wss.on('close', function(){
            console.log('WebServerSocket has been closed');
        });
    };
    
    module.exports = insertData;
    

    我想实现的是将WebSocketServer设置为侦听应用程序的同一端口。 我想通过 服务器 var来自 应用程序.js 服务器.js 但是

    1. 我认为这不是一种优雅的方式
    2. 我不知道该怎么做

    你们怎么看?

    3 回复  |  直到 10 年前
        1
  •  85
  •   Fattie    5 年前

    根据您的代码和注释,这里有一个超级简单的示例,说明它如何协同工作。

    首先 http-server.js -一个典型的快递应用程序,除了我们不使用 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;
    

    现在 ws-server.js 例如,我们从本机节点创建WSS服务器 http.createServer() 。现在,请注意,这是我们导入应用程序的地方,并给出本机http。createServer要使用的应用程序实例。

    使用启动应用程序 PORT=8080 node ws-server.js :

    ( 笔记 您正在启动第二个与套接字相关的文件(ws-server),而不是第一个与http相关的文件。)

    '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}`);
    });
    

    最后,这个示例 index.html 将通过创建POST和Socket“请求”来工作,并显示响应:

    <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>
    

    请注意,您需要一个相当新的浏览器,一个同时具有WebSocket和fetch API的客户端部分,但不管怎样,这都是无关紧要的,它只是提供了它的要点。

        2
  •  11
  •   Fattie    4 年前

    http和ws位于同一端口80,“惊人的Zlatko方法”

    你会有一个文件,说main。js,带有

     var app = express()
    

    以及许多行的快速代码。

    这是完全可以的 以通常的方式尽可能多地使用中间件,无需更改 .

    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 ...
    

    通常在 文件的结尾 你会的

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

    删除它。

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

    无其他更改 在express应用程序文件中。

    在你的网络套接字文件中,说多人游戏。js,您通常会

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

    事实上,更改为

    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);
    

    待定,请注意,让我惊讶的是,WebSocket。服务器确实很自然地想要监听80。

    在文件的末尾

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

    笔记 -启动“多人游戏”。js'文件( 'main.js')。

    它工作得很好。惊人的东西。

        3
  •  1
  •   Priyabrata    5 年前

    以上所有答案都很好。。。 请找到下面的示例代码,看起来有点简单

        var express = require('express')
        var app = express()
        var http = require('http').createServer(app);
        var io = require('socket.io')(http);
    
        app.get('/', function (req, res) {
          res.sendFile(__dirname + '/index.html');
        });
    
        http.listen(process.env.PORT || 3000, function() {
          var host = http.address().address
          var port = http.address().port
          console.log('App listening at http://%s:%s', host, port)
        });
    
        io.on('connection', function(socket) {
          console.log('Client connected to the WebSocket');
    
          socket.on('disconnect', () => {
            console.log('Client disconnected');
          });
    
          socket.on('chat message', function(msg) {
            console.log("Received a chat message");
            io.emit('chat message', msg);
          });
        })
    
    
    推荐文章