Непрерывная передача данных с EventSource


В этой заметке я покажу вам как организовать непрерывную передачу (получение) данных на клиенте (браузере) с помощью JavaScript от сервера. Сервер будет передавать на PHP, немного заденем и Laravel.

Обычно работа с данными, которые необходимо получать от удалённого сервера, находясь на текущей странице, строится просто – периодически вызываем AJAX, получаем информацию, отображаем. На сервере она где-то там хранится и достается в нужный момент. То есть один процесс (например, по крону) получает информацию извне, заносит в базу данных, а второй – отдает её по запросу JS. Это, повторюсь, самый распространенный путь, который устраивает всех в большинстве случаев.

Однако, бывает так, что данные необходимо получать сразу. Ну вот прям сразу, чем быстрее, тем лучше. Делать цикл каждую секунду – это очень плохое решение. Решение лучше – это сокеты. Решение проще – это симбиоз двух решений – EventSource.

По сути мы просто открываем соединение и получаем информацию в потоке. При этом информация, отдаваемая сервером, должна быть в определённом текстовом формате. Давайте для начала реализуем этот формат.

PHP

Создадим вот такую функцию:

public function sendMsg($id, $msg) {
    echo "id: $id" . PHP_EOL;
    echo "data: $msg" . PHP_EOL;
    echo PHP_EOL;
}
Вот и все для сервера. JavaScript Дальше примерный код, который будет вызывать эту функцию с необходимыми данными:

header("Cache-Control: no-store");
header("Content-Type: text/event-stream");


//просто например
$resp["success"] = true;
$resp["contract_etap"] = $cont->contract_etap;

$serverTime = time();
sendMsg($serverTime, json_encode($resp));
То есть мы берем информацию по какому-то контракту и отдаем её. Теперь напишем код на JS, который это будет забирать.

let eventSource = new EventSource("/event");
eventSource.onmessage = function(event) {
    console.log(event.data);
    var obj = JSON.parse(event.data);
    console.log(obj);
    if (obj["success"]){
//тут что-то делаем


        }
    }
};
Несложно, согласитесь? Правда, необходим еще обработать ошибки – так как соединение закроется, если сервер отдаст ошибку 500 например.

В инспекторе кода видно, как по сети идут обращения к серверу и их структура.



Для Laravel

Как обычно создаем маршрут в файле web.php, например, такой:

Route::get('/event', [EventController::class, 'translate']);
Контроллер как обычно

class EventController extends Controller
{
    public function translate(Request $request)
    {
Тут дальше все тоже самое, но используем контекст $this, если функция в этом же классе

$this->sendMsg($serverTime, json_encode($resp));
То есть фактически отличий нет по большому счету. Встрою в вашу систему решение непрерывной передачи данных - пишите, если требуется. Либо проконсультирую на платной основе.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, javascript, php, EventSource, laravel




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.



Урок 2. Введение в роутинг Laravel
Урок 6. Введение в обработку событий Vue.js
Поиск клик графа по алгоритму Брона-Кербоша на C#