使用Socket.io时,为什么AWS ALB会断开连接

时间:2016-12-22 15:09:01

标签: amazon-web-services websocket socket.io amazon-elb

我试图让ALB / Node.js / socket.io解决方案以最简单的形式工作,并且我遇到了握手断开连接的问题。目前,我故意只使用TargetGroup中的一个节点来消除与节点切换和会话粘性相关的变量。

通过我的NAT实例直接连接到节点时,它可以正常工作。断开仅在通过ALB时发生。

以下是我设置的内容:

  • ALB with Listener HTTP 80 - > 8081(无SSL)
  • 2个AZ,都有到互联网的路线(根据ALB的要求)
  • 其中一个AZ中的一个socket.io EC2节点
  • /socket.io/*到socket.io目标组的路径模式(包含我的一个节点)
  • 默认模式也是socket.io目标组
  • 启用了粘性(不应该需要一个节点,但无论如何都要这样做)

以下是我在socket.io节点客户端中看到的内容:

Thu, 22 Dec 2016 20:59:26 GMT socket.io-client:manager opening ws://52.72.198.58
Thu, 22 Dec 2016 20:59:26 GMT engine.io-client:socket creating transport "websocket"
Thu, 22 Dec 2016 20:59:26 GMT engine.io-client:socket setting transport websocket
Thu, 22 Dec 2016 20:59:26 GMT socket.io-client:manager connect attempt will timeout after 20000
Thu, 22 Dec 2016 20:59:26 GMT engine.io-client:socket socket close with reason: "transport close"

以下是我在socket.io节点服务器上看到的内容:

Thu, 22 Dec 2016 20:59:26 GMT socket.io:socket joined room U_qmSv_7gvP_JOFsAAAL
Thu, 22 Dec 2016 20:59:26 GMT socket.io:client client close with reason transport close
Thu, 22 Dec 2016 20:59:26 GMT socket.io:socket closing socket - reason transport close

当我通过我的NAT到同一个socket.io ec2节点时,它都可以在没有传输关闭的情况下工作。

所以不知何故ALB在成功握手期间立即关闭连接。

由于它通过NAT工作,我认为socket.io节点和客户端都可以。因为我在节点中看到了DEBUG条目,所以我知道ALB能够到达socket.io节点。由于我只有一个socket.io节点,因此会话和粘性应该没有问题。

使用ALB时,有什么可能导致立即断开连接?

编辑:我还发现,如果向ELB发出请求的socket.io客户端在EC2节点上,那么它可以工作。这意味着客户端和ELB之间的网络路径中的某些东西。我还没有找到一个案例,除了客户在EC2上之外。它可以通过NAT在任何地方工作,而不是通过ELB。

2 个答案:

答案 0 :(得分:2)

经过大量试验和错误,我能够确定这是由于我的情况下ALB / ELB正在侦听的端口的特定端口范围(80-83)。当握手的HTTP部分工作时,第二个TCP升级阶段断开连接。

与此端口范围相关的VPC没有任何限制,因此问题出在我的客户端和ELB之间的网络中。

总之,这个问题不是AWS中的任何内容,也不是我如何设置资源,它位于AWS之外的其他地方。如果我找到确切的原因,我会将评论发回给这个答案。

答案 1 :(得分:0)

socket = io.connect("https://mywebsite/myroom",{'reconnect':true});

在初始化时增加 HeartbeatTimeout和closeTimeout

socket.on('connect', function(){
    socket.socket.heartbeatTimeout = 500000;
    socket.socket.closeTimeout = 500000;
    socket.on('disconnect', function() {
        socketConnectTimeInterval = setInterval(function () {
        socket.socket.reconnect();
            if(socket.socket.connected) {
                clearInterval(socketConnectTimeInterval);
                 console.log('reconnected');
                 location.reload();
            }
        }, 0);
    });
});

还增加了AWS中负载均衡器的空闲超时时间

enter image description here

希望这可以防止超时问题!