【问题标题】:node.js server with websockets on elastic beanstalk ALB without socket.io在没有 socket.io 的弹性 beanstalk ALB 上具有 websockets 的 node.js 服务器
【发布时间】:2020-03-06 16:53:54
【问题描述】:

我正在尝试使用应用程序负载平衡器 (ALB) 但不使用 socket.io 让 node.js 服务器(使用 express)在弹性 beanstalk (EB) 中使用 websockets 工作(因为 peerjs-server 是我的服务器)我正在尝试运行,它不是用 socket.io 编写的)。

我看过几篇文章建议您必须使用 socket.io(或其他不仅仅依赖于 websockets 的库),但亚马逊表示 ALB 直接支持 websockets。

我的服务器既是 create-react-app 服务器又是 peerjs-server。对于 web UI 和 peerjs ws 连接,它在 dev 端口 9000 上运行良好。

我已经尝试了所有我发现的不同方法,但我还没有让这个工作,我什至看到写的东西表明它不能完成,但似乎我'米关闭。有没有人让这个工作,如果有,怎么做?

【问题讨论】:

    标签: node.js express websocket amazon-elastic-beanstalk peerjs


    【解决方案1】:

    好的,我开始工作了。以下是我为使一切在端口 9000 上正常工作所做的工作。

    在 EB 中,创建应用程序,然后开始创建环境。

    在环境配置中,进入软件部分,告诉它你将使用npm run prod来启动你的服务器。:

    现在,进入负载均衡器部分,如下图所示:

    1. 在端口 9000 上添加监听器
    2. 在端口 9000 上创建一个进程并启用粘性(我称为 peerjsServer)
    3. 为要用于访问服务器的每个 URL 路径添加规则,并将每个规则分配给您创建的进程 (peerjsServer)。还将默认值指向该进程,以便 80 上的健康检查成功通过您的服务器

    您可能需要跳转到 AWS UI 中的 EC2 控制面板,以确保在那里定义了必要的安全组。我想我在 the 上创建了前两个,最后两个是默认创建,但我不记得了。无论如何,他们需要为入站和出站打开端口 9000(默认情况下端口 80 一直存在):

    返回 EB 配置,转到 Instances 部分并确保您的实例具有分配给它的安全组:

    我运行 react-scripts build 来创建包含服务器 UI 生产版本的 /build 目录(这是我在这里不涉及的 create-react-apps 内容)。

    在我的代码中,我使用server.js 启动服务器,这使得服务器同时运行 peerjs-server ws 服务器和 http 服务器。

    const express = require("express");
    const bodyParser = require("body-parser");
    const path = require('path');
    
    const passport = require("passport");
    const users = require("./routes/api/users");
    const games = require("./routes/api/games");
    const Game = require("./src/models/Game");
    
    const WebSocket = require('ws');
    const ExpressPeerServer = require('peerjs-server').ExpressPeerServer;
    
    const app = express();
    const url = require('url');
    
    const port = process.env.PEERSERVERPORT || 9000; 
    
    // WebSocket for making db updates to client.
    const wsserver = require('./wsserver').wsserver
    
    // Server that gets all requests: lobby UI, peerserver, db websocket
    const server = require('http').createServer(app);
    
    wsserver.on('connection', function connection(ws) {
      ws.on('message', msg => {
        ws.send(msg)
      })
    
      ws.on('close', () => {
        console.log('WebSocket was closed')
      })
    });
    
    server.on('upgrade', function upgrade(request, socket, head) {
      const pathname = url.parse(request.url).pathname;
    
      if (pathname === '/ws') {
        wsserver.handleUpgrade(request, socket, head, function done(ws) {
          wsserver.emit('connection', ws, request);
        });    
      }
    });
    
    // Bodyparser middleware
    app.use(
      bodyParser.urlencoded({
        extended: false
      })
    );
    app.use(bodyParser.json());
    
    // Passport middleware
    app.use(passport.initialize());
    // Passport config
    require("./config/passport")(passport);
    
    // Routes -- the /api/* path is defined in the EB load balancer
    app.use("/api/users", users);
    app.use("/api/games", games);
    
    // This is the create-react-apps /build directory of UI code
    app.use(express.static(path.join(__dirname, 'build')));
    app.get('/login', function (req, res) {
      res.sendFile(path.join(__dirname, 'build', 'index.html'));
    });
    
    // These are the paths that are defined in the EB load balancer
    app.get('/logout', function (req, res) {
      res.sendFile(path.join(__dirname, 'build', 'index.html'));
    });
    app.get('/register', function (req, res) {
      res.sendFile(path.join(__dirname, 'build', 'index.html'));
    });
    app.get('/dashboard', function (req, res) {
      res.sendFile(path.join(__dirname, 'build', 'index.html'));
    });
    
    // Peer server for making WebRTC connections between game clients.
    const options = { 
        debug: true
    }
    const peerserver = ExpressPeerServer(server, options);
    app.use('/peerserver', peerserver);
    
    app.use(express.static(path.join(__dirname, 'src')));
    
    app.get('*', function(req, res) {
      res.sendFile(path.join(__dirname, 'src', 'index.html'));
    });
    
    peerserver.on('disconnect', (client) => {
      console.log('Delete the game if the host client disconnects');
      Game.deleteMany({ hostPeerId: client })
        .then(() => {
          wsserver.clients.forEach(function each(client) {
            if (client.readyState === WebSocket.OPEN) {
              client.send("refreshGames");
            }
          })
        })
        .catch(err => console.log(err));
    });
    
    server.listen( port, () => console.log(`Server is up and running on port ${port} !`))
    

    然后在我的package.json中,我设置了prod的脚本来运行上面的server.js来启动服务器,我之前放在Software部分的npm run prod是什么调用它以使服务器运行:

      ...
      "scripts": {
        "start": "set PORT=8081&& react-scripts start",
        "prod": "node server.js",
      ...
    

    完成所有这些之后,我现在有一个正在运行的 EB 服务器,它使用 ALB 并在端口 9000 上处理 websocket (ws) 和 UI (http) 流量。

    【讨论】:

      猜你喜欢
      • 2014-04-11
      • 2013-10-30
      • 2011-12-27
      • 1970-01-01
      • 2013-02-16
      • 2016-01-16
      • 2013-06-02
      • 2016-09-07
      • 1970-01-01
      相关资源
      最近更新 更多