Websocket closing after 60 seconds of being idle while connection node server using AWS ELB
Asked Answered
H

3

13

I have one node server running on EC2 instance and client is also running on same EC2 instance, Client open websocket connection to communicate node server, it is working in QA and Dev AWS environment but same web connection is getting close after 60 seconds of being idle in prod environment ,I am running client and node server behind ELB in aws environment.

Client Code:

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

Node server Code below:

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: {}
    };
        
 });
});
Hackle answered 13/2, 2018 at 0:0 Comment(0)
M
21

By default, Elastic Load Balancing sets the idle timeout value to 60 seconds. Therefore, if the target doesn't send some data at least every 60 seconds while the request is in flight, the load balancer can close the front-end connection. To ensure that lengthy operations such as file uploads have time to complete, send at least 1 byte of data before each idle timeout period elapses, and increase the length of the idle timeout period as needed.

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

Note that your interests are best served by periodically sending traffic to keep the connection alive. You can set the idle timeout to up to 4000 seconds in an Application Load Balancer, but you will find that stateful intermediate network infrastructure (firewalls, NAT devices) tends to reset connections before they are actually idle for so long.

Myall answered 13/2, 2018 at 10:40 Comment(1)
Sending regular websocket messages to avoid the 60 second timeout worked for me.Professorate
K
3

PING!

Write a ping implementation (or a nil message implementation)...

...otherwise the AWS proxy (probably nginx) will shut down the connection after a period of inactivity (60 seconds in your case, but it's a bit different on different systems).

K answered 13/2, 2018 at 4:29 Comment(0)
S
2

Do you use NGINX? Their requests timeout after 60 seconds.

You can extended the timeout in the NGINX configuration file for your websockets specific location.

In your case it could look something like this when extending the timeout to an hour:

...

location / {
   ...
   proxy_pass http://127.0.0.1:8443;
   ...

   proxy_read_timeout 3600;
   proxy_send_timeout 3600; 
   ...
}

Also see this website for more information:

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

Sialagogue answered 7/3, 2022 at 17:4 Comment(1)
If you use apache, it depends on the method of proxy; stack will solve your problemsZarla

© 2022 - 2024 — McMap. All rights reserved.