Поиск
Лог Рег    Штуки    Проекты

SSE уведомления от ларавель

Предупреждение! Я опытный пользователь персонального компьютера и программы МС Ворд и Звукозапись. Однако ряд терминов и определений в этой статье могу употребить не верно. Сообщите о моих ошибках, если они найдутся.

Суть

Есть две системы. Одна разрабатывается мной и на ней отображены лица сотрудников ИПК. Страница первой системы открыта на большой сенсорной панеле на входе. По тычку в лицо соответствующий человек записывается в базу, выделяется цветом вовремя пришедшего или опаздавшего и т.д. Вторая — это СКУД от RusGuard. 

Предусмотрена система синхронизации моей системы со скудом. Но работает она так: каждые N секунд уходит аякс на сервер, сервер получает данные от MS SQL на скуде за текущее число, парсит тех, кто есть в скуде, но не отмечен на странице моей системы (открытой на сенсорной панельке) и делает по ним джаваскриптовый клик. 

Мне не нравится это решение.

Решение

Метод проб и ошибок привел меня к следующему решению. На сервере скуда в Конфигурации_системы-Реакции добавляем расписание от 00:00 до 23:59, например. Создаем событие, указываем типы и источники событий, во вкладке Сотрудников не забываем указать сотрудников (по умолчанию никто не стоит). Привязываем расписание к событию. Создаем действие Запуска программы. В пути прописываем путь до файла bat (русгуард только их в данном случае принимает). В корневой каталог дублирую каталог файла.

В батнике курл или вгет делает гет запрос к моей системе с указанием ключа в мд5.

У себя в шаблоне обозначаю EventSource

const eventSource = new EventSource("/sse");
eventSource.onmessage = function (event) {
    console.log(event['data']);
    if (event['data'] === 'update') {
        check_cart();
    }
};

eventSource.onopen = function (e) {
    console.log("Открыто соединение");
};
eventSource.onerror = function (e) { console.log(e); };

Пишем роуты для нашего события и потока.

Route::get('/sse', 'PeopleController@sse');
Route::get('/upd/{key}', 'PeopleController@scud_upd_event');

И самое кайфоное. Создаем метод для события, который запоминает в кеш необходимость обновить данные на открытой странице моей системы:

public function scud_upd_event($key) {
     if(md5(self::$key) === $key){
        Cache::forget('update_event_cache');
        Cache::put('update_event_cache', 'true', 3500);
     }
}

И говорим, что сервак транслирует поток, реализуем в нем цикл с какой-то например задержкой, который работает до появления данных в "update_event_cache" кеша. После чего отправляем клиенту информацию о необходимости совершения аякса, который запустит клики по лицам, пикнувшимся в скуде, но не тыкнувшимся на панеле:

 public function sse() {
     return response()->stream(function () {
         while (true) {
             usleep(1000);
                 if (Cache::has('update_event_cache')) {
                     Cache::forget('update_event_cache');
                         echo "data: " . 'update' . "\n\n";
                         ob_flush();
                         flush();  
                      }
                  }
      }, 200, [
          'Cache-Control' => 'no-cache',
          'Content-Type' => 'text/event-stream',
      ]);
}

Технология server sent events помогла нам установить постоянное соединение с сервера с клиентом, в котором клиену в реальном времени можно дослать информацию по событию, произошедшему на сервере.

Ключевые фрагменты на гитхаб


Тату Алексеевой

Jul-ya

Новый логотип ГлоАгента

Экспресс-сайт «Егозы»