【问题标题】:Websocket closing after 60 seconds of being idle while connection node server using AWS ELB使用 AWS ELB 连接节点服务器时,Websocket 在空闲 60 秒后关闭
【发布时间】:2022-03-08 01:04:39
【问题描述】:

我有一个节点服务器在 EC2 实例上运行,客户端也在同一个 EC2 实例上运行,客户端打开 websocket 连接以与节点服务器通信,它在 QA 和开发 AWS 环境中工作,但相同的 web 连接在 60 秒后关闭在 prod 环境中处于空闲状态,我在 aws 环境中在 ELB 后面运行客户端和节点服务器。

客户代码:

ws = new WebSocket('ws://localhost:8443');
        
ws.onclose = function () {
    console.log("Websocket connection has been closed.");
    clientObj.emit('LogoffSuccess', 'LogoffSuccessfully');
};
 
ws.onerror=function(event)
{
    console.log(event.data);
};
            
ws.addEventListener('open', function (event) {
    console.log('Websocket connection has been opened');
    ws.send(JSON.stringify(loginCreds));
});
    
    

节点服务器代码如下:

const wss = new WebSocket.Server({ server: app });
const clients = {};
const idMap = {};
    
wss.on(`connection`, ws => {
  const headers = ws.upgradeReq.headers;
  const host = headers.host;
  const key = ws.upgradeReq.headers[`sec-websocket-key`];
    
  ctiServer.on(`responseMessage`, message => {
   clients[message.AgentId].send(JSON.stringify(message));
  });
    
  ws.on(`message`, message => {
    log.info(`Message received. Host: ${host}, Msg: ${message}`);
    if (JSON.parse(message).EventName === `Login`) {
      clients[JSON.parse(message).AgentId] = ws;
      idMap[key] = JSON.parse(message).AgentId;
     }
     ctiServer.processIncomingRequest(message);
  });
    
  ws.on(`close`, () => {
    log.info(`Connection closed. Host: ${host}`);

    const message = {
      EventName: `Logoff`,
      AgentId: idMap[key],
      EventData: {}
    };
        
 });
});

【问题讨论】:

    标签: node.js amazon-web-services amazon-ec2 websocket aws-elb


    【解决方案1】:

    默认情况下,Elastic Load Balancing 将空闲超时值设置为 60 秒。因此,如果在请求进行时目标没有至少每 60 秒发送一次数据,负载均衡器可以关闭前端连接。为确保文件上传等冗长的操作有时间完成,请在每个空闲超时时间过去之前至少发送 1 个字节的数据,并根据需要增加空闲超时时间的长度。

    https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#connection-idle-timeout

    请注意,定期发送流量以保持连接活跃,最能满足您的兴趣。您可以在 Application Load Balancer 中将空闲超时设置为最多 4000 秒,但您会发现有状态的中间网络基础设施(防火墙、NAT 设备)往往会在连接真正空闲这么长时间之前重置连接。

    【讨论】:

    • 发送常规 websocket 消息以避免 60 秒超时对我有用。
    【解决方案2】:

    平!

    编写一个ping实现(或nil消息实现)...

    ...否则 AWS 代理(可能是 nginx)将在一段时间不活动后关闭连接(在您的情况下为 60 秒,但在不同系统上会有所不同)。

    【讨论】:

      【解决方案3】:

      你使用 NGINX 吗?他们的请求在 60 秒后超时。

      您可以在 NGINX 配置文件中为您的 websockets 特定位置延长超时时间。

      在您的情况下,将超时时间延长到一小时时,它可能看起来像这样:

      ...
      
      location / {
         ...
         proxy_pass http://127.0.0.1:8443;
         ...
      
         proxy_read_timeout 3600;
         proxy_send_timeout 3600; 
         ...
      }
      

      有关详细信息,另请参阅此网站:

      https://ubiq.co/tech-blog/increase-request-timeout-nginx/

      https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout

      https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-11
        • 1970-01-01
        • 2015-03-31
        • 2012-02-20
        • 1970-01-01
        相关资源
        最近更新 更多