Зачем мне нужен ping-pong для обнаружения обрывов соединения с websocket, если я уже повторно подключаюсь к onclose()?

#javascript #websocket #ping #pong

#javascript #websocket #пинг #понг

Вопрос:

У меня есть код, который подключается к внешнему API WebSocket, который выглядит следующим образом:

 const WebSocket = require('ws')

const ws = new WebSocket('wss://example.com/')

const connectExternalAPI() => {
    ws.onopen = () => { ws.send(JSON.stringify('example': 'message')) }

    ws.onerror = (event) => { console.error(event) }

    ws.onmessage = (event) => { console.log(event.data) }

    ws.onclose = (event) => {
        console.error(event)
        setTimeout(connectExternalAPI, 10000)
    }
}
  

Поскольку я уже пытаюсь повторно подключиться к API каждый раз, когда соединение получает an onclose , в чем необходимость дополнительной реализации ping-pong для обнаружения разрывов соединения (и попытки повторного подключения), когда это уже выполняет то же самое?

Существуют ли обстоятельства, при которых onclose is не срабатывает, даже если соединение могло прерваться?

Ответ №1:

Если соединение явно закрыто, вы получите сообщение onclose почти сразу, но если соединение разорвано, например, при отключении кабеля Ethernet, потребуется некоторое время, чтобы получить сообщение onclose , вероятно, не раньше, чем TCP обнаружит потерю подключения. Это может занять много минут, в зависимости от ваших настроек.

Кстати, это не обязательно должен быть Ping / Pong; сердцебиение, отправленное сервером, полученное и обработанное в браузере, также будет работать, и иногда его проще реализовать.

Комментарии:

1. Я вижу, всегда ли в конечном итоге он получает onclose событие, хотя после того, как TCP обнаружил потерю подключения? Я не возражаю, что они задерживаются, если это всего на пару минут.

2. Насколько я знаю и испытал, он осторожно сказал 8-), это в конечном итоге произойдет, да. Однако в Firefox я видел до 10 минут. Я всегда добавляю сердцебиение сервера, чтобы убедиться.

3. Спасибо! В моем случае сам мой сервер подключается к внешнему веб-сокету, поэтому он не будет обнаружен браузером, но мое приложение узла обнаружит его.

4. Если у вас есть полный контроль, я полагаю, вы могли бы каким-то образом установить время ожидания пользователя TCP, как я думаю, это называется официально, на 10 секунд или что-то в этом роде, и покончить с этим.

5. О, хорошо, отлично, рассмотрю это. Спасибо!