Закрытие веб-сокета после 60 секунд простоя, когда сервер узла соединения использует AWS ELB
У меня есть один сервер узлов, работающий на экземпляре EC2, и клиент также работает на том же экземпляре EC2, клиент открывает соединение через веб-сокет для связи с сервером узлов, он работает в среде QA и Dev AWS, но одно и то же веб-соединение закрывается после 60 секунд простоя в среде prod я запускаю клиент и сервер узла за ELB в среде aws.
Код клиента:
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: {}
};
});
});
3 ответа
По умолчанию Elastic Load Balancing устанавливает значение тайм-аута простоя на 60 секунд. Поэтому, если цель не отправляет некоторые данные, по крайней мере, каждые 60 секунд во время выполнения запроса, балансировщик нагрузки может закрыть внешнее соединение. Чтобы гарантировать, что длительные операции, такие как выгрузка файлов, успеют завершиться, отправьте по крайней мере 1 байт данных до истечения каждого периода простоя и увеличьте продолжительность периода простоя по мере необходимости.
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html
Обратите внимание, что вашим интересам лучше всего периодически отправлять трафик, чтобы поддерживать соединение. Вы можете установить время простоя до 4000 секунд в Application Load Balancer, но вы обнаружите, что промежуточная сетевая инфраструктура с состоянием (брандмауэры, устройства NAT) имеет тенденцию сбрасывать соединения, прежде чем они фактически простаивают так долго.
ПИНГ!
Напишите реализацию ping (или nil
реализация сообщения)...
... в противном случае прокси-сервер AWS (возможно, nginx) отключит соединение после некоторого периода бездействия (в вашем случае 60 секунд, но в разных системах это немного отличается).
Вы используете NGINX? Их запросы истекают через 60 секунд.
Вы можете продлить тайм-аут в файле конфигурации NGINX для конкретного местоположения вашего веб-сокета.
В вашем случае это может выглядеть примерно так при увеличении времени ожидания до часа:
...
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