Ваш существующий код не требует много изменений для перехода к отправленным на сервер событиям.
На внешнем интерфейсе то, что вы используете в качестве обработчика success
, становится тем, что становится событием message
обработчик. (В духе рефакторинга по одному шагу за раз, вы можете продолжить до pu sh готового HTML.)
Вы сбрасываете таймер интервала на входной стороне, и вместо этого он перемещается в back-end.
(Последствия этого состоят в том, что сокет остается открытым, а процесс PHP теперь постоянно работает, а не запускается и выключается при каждом опросе. Это может влияет на масштабирование для большого количества клиентов.)
Что нужно изменить на бэкэнде, так это обернуть то, что у вас есть в al oop примерно так:
<?php
header("Content-Type: text/event-stream");
$prev_d = null;
while(true){
$d = ...
if($d != $prev_d){
echo "data:".$d."\n\n";
@ob_flush();@flush();
$prev_d = $d;
}
usleep(100000); //Poll every 0.1 seconds
}
Как В качестве первого шага вы можете установить $d
, вызвав существующий скрипт PHP!
Даже после этих простых изменений ваш общий процесс теперь намного лучше. Да, база данных SQL все еще опрашивается один раз каждые 100 мс для каждого активного пользователя, но теперь вы отправляете данные только через сокет, когда что-то действительно изменилось.
Следующим шагом будет размещение всех данных c HTML на стороне клиента, а не внутри скрипта PHP. И тогда скрипт просто отправляет обратно результаты запроса SQL. Это более эффективно, так что вы будете иметь немного меньшую нагрузку на сервер и пропускную способность. Однако главное преимущество заключается в том, что это облегчит понимание и обслуживание системы. Также проще переносить на другие языки или на другие типы клиентов.
Основной l oop станет примерно таким:
<?php
header("Content-Type: text/event-stream");
$prev_sql = null;
while(true){
$panicsql = getConnection()->query("SELECT * FROM Units WHERE Status='PANIC'");
if($panicsql != $prev_sql){
$d = json_encode($panicsql);
echo "data:".$d."\n\n";
@ob_flush();@flush();
$prev_sql = $panicsql;
}
usleep(100000); //Poll every 0.1 seconds
}