应用程序负载均衡器是否支持WebSockets?

时间:2016-09-05 18:34:58

标签: amazon-web-services websocket elastic-load-balancer

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

ALB实际上支持WebSocket吗? AWS文档与此相矛盾。 This page表示它只支持HTTP和HTTPS。没有设置ALB以支持WebSocket的指南。

5 个答案:

答案 0 :(得分:29)

我能够让WebSockets使用新的Application Load Balancer(ALB)。

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

Add Target Group with Stickiness

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

Add Listen rule for 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
        };
    }
})();

答案 1 :(得分:1)

应用程序负载均衡器支持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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

ALB(应用程序负载平衡器)支持websocket。您可以在这里查看https://aws.amazon.com/blogs/aws/new-aws-application-load-balancer/ enter image description here

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

SnapShot from the above blog

答案 4 :(得分:0)

关于nodejs 当我们在客户端上使用套接字io并调用socket.js liberary
像这样

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

这确实解决了我的问题