Непрерывная передача данных с 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 - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.