Express 和 WebSocket 监听同一个端口 [英] Express and WebSocket listening on the same port

查看:42
本文介绍了Express 和 WebSocket 监听同一个端口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

这是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(只有重要的几行)

And here is the server.js (only the important lines)

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 设置为侦听应用程序的同一端口.我想过将 server var 从 app.js 传递给 server.js 但是

What I would like to achieve is to set the WebSocketServer in a way that it listen to the same port of the app. I thought about passing the server var from app.js to server.js but

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

大家怎么看?

推荐答案

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

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

首先,http-server.js - 一个典型的 express 应用,除了我们不使用 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 提供应用程序实例以供使用.

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.

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

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

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

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

最后,这个示例 index.html 将通过创建一个 POST 和一个套接字请求"来工作.并显示响应:

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>

请注意,您需要一个相当新的浏览器,该浏览器具有此客户端部分的 WebSocket 和 fetch API,但这无关紧要,它只是为您提供了要点.

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.

这篇关于Express 和 WebSocket 监听同一个端口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆