Как читать wss:// поток в php без библиотек (streaming api vk)

92
26 февраля 2022, 21:10

Streaming api vk позволяет получать события со всего вк, и реализовано это через wss:// протокол. Насколько я нагуглил, wss:// не поддерживается PHP по умолчанию.

Документация по streaming api:

Как это реализовать без использования библиотек/перекомпиляции php и т.д.?

UPD 1: по сути wss, это ssl над tcp, и в теории должен работать следующий код, но почему-то выдает 404 страницу.

$socket = stream_socket_client("ssl://$endpoint:443/stream?key=$key", $errno, $errstr, 5, STREAM_CLIENT_CONNECT);
        $header = "GET / HTTP/1.1\r\n" .
            "Content-Type:application/json\r\n" .
            "Host: localhost\r\n" .
            "Upgrade: websocket\r\n" .
            "Connection: Upgrade\r\n" .
            "Sec-WebSocket-Version: 13\r\n\r\n";
        fwrite($socket, $header);
        while (!feof($socket)) {
            $context = fgets($socket, 1024);
            print_r($context);
        }
        fclose($socket);
Answer 1

Это получилось сделать! Правда подводных камней было много.
Для тех, кто попал сюда с таким же вопросом - прочитайте про реализацию вебсокет протокола

  • Необходимо действительно стучаться на ssl:// с 443 портом.
  • При отправке заголовков после подключения, необходимо query часть запроса засунуть вот в таком виде

$header = "GET /stream?key={$key} HTTP/1.1\r\n" .
"host: streaming.vk.com:443\r\n" .
"user-agent:websocket-client-php\r\n" .
"connection:Upgrade\r\n" .
"upgrade:websocket\r\n" .
"sec-websocket-key: $key\r\n" .
"sec-websocket-version:13\r\n\r\n";
fwrite($this->socket, $header);

  • Также должен присутствовать заголовок sec-websocket-key с сгенерированным ключом. Подробнее читайте на сайте про реализацию вебсокет протокола. Вот реализация генератора на PHP
function generateKey() {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"$&/()=[]{}0123456789';
        $key = '';
        $chars_length = strlen($chars);
        for ($i = 0; $i < 16; $i++) $key .= $chars[mt_rand(0, $chars_length - 1)];
        return base64_encode($key);
}

А дальше просто идет вычисление длинны payload, считывание payload, ловля PING сообщений от вк и отправка PONG.

Полностью класс реализации работы с Streaming вы можете посмотреть в моей библиотеке, либо в master ветке, либо в testing по пути src/Streaming.php. Там будет актуальная версия

READ ALSO
switch &lt; или &gt; в (int)

switch < или > в (int)

Возможно ли в switch сделать проверку на < ( больше ) или > ( меньше )

171
RestAPI - как реализовать возврат данных?

RestAPI - как реализовать возврат данных?

В общем делаю проект на Laravel с RestApi и vuejsВозврат products делаю с использованием ApiResource в Laravel

76
работа с массивом через foreach

работа с массивом через foreach

Стоит задача вывести из БД таблицу с заголовкомДля отображения заголовка использую foreach, но если использовать такой код:

77
Названия тестов + нумерация в codeception

Названия тестов + нумерация в codeception

Не могу найти в документации имеется ли возможность в codeception делать нумерованный вывод тестов в консоль, а так же не могу найти как менять...

132