Отправка пинг / понг фрейма через браузер

Я продолжаю читать о сообщениях пинг / понг в веб-сокетах, чтобы поддерживать соединение, но я не уверен, что это такое. Это определенный тип кадра? (Я не вижу методов в объекте javascript WebSocket в chrome, связанных с пинг-понгом). Или это просто шаблон проектирования (например, я буквально отправляю "ping" или любую другую строку на сервер и заставляю ее отвечать). Связан ли пинг-понг с фреймами продолжения?

Причина, по которой я спрашиваю, состоит в том, что я использую инфраструктуру Python, которая работает за Mongrel2, поэтому мне интересно, есть ли способ отправить Mongrel2 конкретное сообщение ping/pong, которое сообщит ему, чтобы поддерживать соединение без моего приложения на python беспокоиться об этом. Я полагаю, это похоже на наличие отдельного метода HTTP для него. И я полагаю, что выделенный фрейм сообщения ping/pong может быть проще (с меньшей нагрузкой на сервер и сеть), чем строка "ping", хотя это, вероятно, не будет иметь большого значения.

РЕДАКТИРОВАТЬ: Я только что посмотрел на RFC 6455 и похоже, что Ping и Pong, безусловно, являются типами управления кадрами с их собственными кодами операций. Так как же отправить кадр Ping из JavaScript в Chrome?

4 ответа

Решение

Не существует API Javascript для отправки фреймов ping или получения фреймов понга. Это либо поддерживается вашим браузером, либо нет. Также нет API для включения, настройки или определения того, поддерживает ли браузер фреймы пинг-понга и использует их. Было обсуждение создания API пинг / понга Javascript для этого. Существует вероятность того, что пинг может быть конфигурируемым / обнаруживаемым в будущем, но маловероятно, что Javascript сможет напрямую отправлять и получать кадры пинг / понга.

Однако, если вы управляете как клиентским, так и серверным кодом, вы можете легко добавить поддержку пинг-понга на более высоком уровне. Вам понадобится заголовок / метаданные типа сообщения в вашем сообщении, если у вас его еще нет, но это довольно просто. Если вы не планируете отправлять эхо-запросы сотни раз в секунду или у вас есть тысячи одновременных клиентов, накладные расходы будут довольно минимальными, чтобы сделать это самостоятельно.

Ping предназначен для отправки только с сервера на клиент, и браузер должен ответить как можно скорее с Pong OpCode, автоматически. Так что вам не нужно беспокоиться об этом на более высоком уровне.

Хотя не все браузеры поддерживают стандарт, как они предполагают, у них могут быть некоторые различия в реализации такого механизма, и это может даже означать, что функциональность ответа Pong отсутствует. Но лично я использую Ping / Pong и никогда не видел клиента, который не реализует этот тип OpCode и автоматический ответ на низкоуровневой реализации на стороне клиента.

возможное решение в js

В случае, если инициатива сервера WebSocket отключает ws ссылка через несколько минут между сервером и клиентом не будет отправлено никаких сообщений.

  1. клиент отправляет заказ ping сообщение, чтобы остаться в живых, используя keepAlive функция

  2. сервер игнорирует ping сообщение и ответ на заказ pong сообщение

var timerID = 0; 
function keepAlive() { 
    var timeout = 20000;  
    if (webSocket.readyState == webSocket.OPEN) {  
        webSocket.send('');  
    }  
    timerId = setTimeout(keepAlive, timeout);  
}  
function cancelKeepAlive() {  
    if (timerId) {  
        clearTimeout(timerId);  
    }  
}

Нет.

Я попытался реализовать пинг. Кажется, я не могу заставить клиент WebSocket браузера установить любой код операции, кроме 0x1 (строка) и 0x2 (двоичный).

      const socket = new WebSocket(url);
ping() {
    if (socket?.readyState !== WebSocket.OPEN) {
      return;
    }
    const buffer = new ArrayBuffer(7);
    const dataView = new DataView(buffer);
    dataView.setInt8(0, 0x89);
    dataView.setInt8(1, 0x00);
    dataView.setInt8(2, 0x48);
    dataView.setInt8(3, 0x65);
    dataView.setInt8(4, 0x6c);
    dataView.setInt8(5, 0x6c);
    dataView.setInt8(6, 0x6f);
    socket.send(buffer);
  }
socket.addEventListener('open', ping);

Этот код должен отправить последний кадр проверки связи (0x8)(код операции 0x09) с телом «привет», но браузер отправляет последний кадр в двоичном формате (0x82) с телом «привет», где — данные 0x89.

Другие вопросы по тегам