Express和WebSocket在同一端口上监听

时间:2016-01-15 10:23:34

标签: javascript node.js websocket

我有一个app.js,用于在收到一些POST数据时触发两个事件:

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

    这是 app.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');
    });
    

    这是 server.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从 app.js 传递到 server.js ,但是

    1. 我认为这不是一种优雅的方式
    2. 我不知道该怎么做
    3. 你们觉得怎么样?

3 个答案:

答案 0 :(得分:35)

根据您的代码和评论,这是一个如何协同工作的简单示例。

首先, 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 示例,我们从本地http.createServer()节点创建WSS服务器。现在,请注意,这是我们导入应用程序的位置,并为此本机http.createServer提供要使用的应用程序实例。

使用PORT=8080 node ws-server.js

启动应用
'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和套接字“请求”来工作并显示响应:

<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的客户端部分,但无论如何它都是无关紧要的,它只是为您提供了它的主旨。

答案 1 :(得分:2)

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应用程序文件中的

没有其他更改

在您的websocket文件中,例如multiplayer.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);

在该文件的末尾

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

注意!-启动“ multiplayer.js”文件(不是“ main.js”)。

它完美地工作。很棒的东西。

答案 2 :(得分:0)

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

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