39

我有一个最初配置为使用 Classic Load Balancer 的 Elastic Beanstalk 应用程序。我发现这在通过 WebSocket 连接时会导致错误。因此,我将应用程序配置为使用 Application Load Balancer,因为有人告诉我 ALB 支持 WebSocket。但是,他们似乎没有:尝试通过 WebSocket 连接到我的 ALB 时遇到完全相同的错误。

ALB 真的支持 WebSocket 吗?AWS 文档在这方面是矛盾的。这个页面说它只支持 HTTP 和 HTTPS。没有设置 ALB 以支持 WebSocket 的指南。

4

5 回答 5

45

我能够让 WebSockets 与新的应用程序负载均衡器 (ALB) 一起工作。

首先,为您的 ALB 创建一个新的目标组。此目标组应使用与您的应用程序相同的端口,并且需要配置运行状况检查。但是,主要区别在于您必须启用粘性。

添加具有粘性的目标组

接下来,将新的侦听器规则添加到您的 ALB。此规则必须有一个路径来路由 WebSocket 设置 -- /socket.io。此外,将目标组名称设置为您刚刚创建的目标组。

为 WebSocket 添加监听规则

我正在为我的服务器使用 Node/Hapi/Socket.io(在源自 Amazon Linux AMI 的实例上运行)。基本设置是:

const hapi = require('hapi');
const websocket = require('./WebSocket');

var server = new hapi.Server();
server.connection(config.Application);
websocket.Initialize(server.listener);

WebSocket.js 在哪里

var io = null;

module.exports = {

    Initialize: function (http) {

        io = require('socket.io')(http);

        io.on('connection', function (socket) {
            console.log('Websocket ' + socket.id + ' connected.');

            socket.on('disconnect', function () {
                console.log('Websocket ' + socket.id + ' disconnected.');
            });
        });
    }
};

我正在为我的客户端使用 Angular 1.5x,带有 socket.io-client。如下配置 WebSocket 客户端选项很重要,否则您将无法连接。

(function () {

    'use strict';

    angular
        .module('XXXXX', [])
        .run(runHandler);

    runHandler.$inject = ['WebSocketService'];

    function runHandler(WebSocketService) {
       WebSocketService.Initialize();
    }
})();

WebSocket 服务:

(function () {

    'use strict';

    angular
        .module('XXXXX')
        .factory('WebSocketService', WebSocketService);

    WebSocketService.$inject = [];

    function WebSocketService() {

        var socket = null;

        function initialize() {

            var url = 'http://' + ALB_URL + ':5800';

            socket = io(url, {transports: ['websocket'], upgrade: false});

            socket.on('connect', function () {
                console.log('Socket connected');
            });

            socket.on('disconnect', function () {
                console.log('Socket disconnected');
            });
        }

        return {
            Initialize: initialize
        };
    }
})();
于 2016-11-04T12:55:34.903 回答
5

ALB 支持 Websocket,但如果实例至少每隔“空闲超时”秒发送一些数据,负载均衡器可以关闭连接。

于 2016-11-06T14:23:48.283 回答
2

应用负载均衡器支持 websocket。但是直到 2017 年 2 月 23 日才支持 websocket 健康检查。他们可能会在以后添加一个选项。当您想在 Application Load Balancer 后面使用 websocket 时,您需要为目标组设置 HTTP 或 HTTPS 运行状况检查。

来自 AWS 文档:“请注意,运行状况检查不支持 WebSockets。”

参考http ://docs.aws.amazon.com/elasticloadbalancing/latest/application/target-group-health-checks.html

于 2017-02-23T14:06:31.877 回答
1

ALB(应用程序负载平衡器)支持 websocket。您可以在此处查看https://aws.amazon.com/blogs/aws/new-aws-application-load-balancer/在此处输入图像描述

ALB 还会根据配置的空闲超时关闭连接。

来自上述博客的快照

于 2018-10-26T10:34:03.147 回答
-3

在nodejs方面当我们在客户端使用socket io并
像这样调用socket.js库时

const socket = io('domain.com');

我观察到的是,当我将 Http 指定为协议时,它将调用重定向到 ws://domain.com,但是当我指定 https 时,它重定向到 wss://domain.com 并且我收到此错误失败:WebSocket 期间出错握手:意外的响应代码:400 我所做的是我指定的

const socket = io(window.location.origin, {reconnect: true,transports: ['websocket']});

这确实解决了我的问题

于 2019-12-12T13:28:24.327 回答