Каков наиболее оптимальный способ создания системы MDT / CAD? (AJAX, SSE, WebSocket) - PullRequest
0 голосов
/ 20 января 2020

Здравствуйте, кто бы ни читал,

Я долгое время работал над бэкэндом для веб-сайта, который предоставляет c Мобильный терминал данных и систему автоматизированной диспетчеризации для ролевой игры в Интернете.

Первоначально я использовал AJAX вызовы для setInterval, который обновляет часть страницы буквально за 100 мс i sh, а на стороне PHP он выполняет запрос SQL.

Как вы можете себе представить, это оказалось очень медленным и в итоге даже удается связываться с сессиями и регистрировать людей как других людей (не спрашивайте, как ... я не знаю). Я читал о WebSockets и SSE, но мне нужно действительно выбрать метод и перенести всю систему, чтобы мой простой вопрос был ...

Каков наилучший способ оптимизации моей системы? И могу ли я привести пример или два на практике?

Большое спасибо за чтение,

Пример AJAX звоните

JQuery


      if (obs) {
        obs = false;
      }

      $.ajax({
        type:"GET",
        url: "mdt.php", 
        data: {  },
        success: function(result) {
          $("#mdt").html(result);
        }
      });
    };

setInterval(function() { if (!obs) { if (!paused) { refreshmdt(); } } }, 750);

мдт. php

session_start();
include("../config.php");
include("../backend.php");

$panicsql = getConnection()->query("SELECT * FROM Units WHERE Status='PANIC'");

if ($panicsql->num_rows > 0) {
    echo "<script>togglePanic('activate');</script>";
} else {
    echo "<script>togglePanic('deactivate');</script>";
}
?>
<!-- Terminal -->
<div class="col-md-6 col-sm-6 col-xs-12">
                <div class="x_panel">
                  <div class="x_title">
                    <h2><i class="fa fa-mobile"> Terminal</i></h2>
                    <ul class="nav navbar-right panel_toolbox" id="terminal">
                      <li>
                        <a href="bookoff.php"><button class="btn btn-block btn-danger"><i class="fa fa-sign-out"></i> Book Off</button></a>
                      </li>
                    </ul>
                    <div class="clearfix"></div>
                  </div>
                  <div class="x_content" id="" style="height:74.3vh;min-height:70vh;max-height:74.3vh;overflow:auto;text-align:center;">

                    <?php include("Ajax/status.php"); ?>
                    <br />
                    <h4><b>Change Status:</b></h4>
                    <br />
                    <p>
                      <a onclick="javascript:changeStatus('AVAILABLE');" class="btn btn-sq-sm btn-success">
                        <i class="fa fa-check fa-2x"></i><br/>
                        AVAILABLE
                      </a>
                      <a onclick="javascript:changeStatus('EN ROUTE');" class="btn btn-sq-sm btn-warning">
                        <i class="fa fa-taxi fa-2x"></i><br/>
                        EN ROUTE
                      </a>
                      <a onclick="javascript:changeStatus('ON SCENE');" class="btn btn-sq-sm btn-primary">
                        <i class="fa fa-map-marker fa-2x"></i><br/>
                        ON SCENE
                      </a>
                      <a onclick="javascript:changeStatus('PRISONER');" class="btn btn-sq-sm btn-info">
                        <i class="fa fa-user fa-2x"></i><br/>
                        PRISONER
                      </a>
                      <a onclick="javascript:changeStatus('UNAVAILABLE');" class="btn btn-sq-sm btn-default">
                        <i class="fa fa-times fa-2x"></i><br/>
                        UNAVAIL..
                      </a>
                      <a onclick="javascript:changeStatus('PANIC');startPanic();" class="btn btn-sq btn-block btn-danger">
                        <i class="fa fa-exclamation-triangle fa-1x"></i>
                        PANIC
                      </a>
                    </p>
                    <hr />
                    <p>
                      <a data-toggle="modal" data-target="#pnc" class="btn btn-sq btn-default">
                        <i class="fa fa-database fa-5x"></i><br/>
                        PNC
                      </a>
                      <a data-toggle="modal" data-target="#report" class="btn btn-sq btn-default">
                        <i class="fa fa-edit fa-5x"></i><br/>
                        REPORT
                      </a>
                    </p>

                  </div>
                </div>
              </div>

              <!-- Active Incident / Observations -->
              <div class="col-md-6 col-sm-6 col-xs-12">
                <div class="x_panel">
                  <div class="x_title">
                    <h2><i class="fa fa-comments-o"> Active Incident</i></h2>
                    <ul class="nav navbar-right panel_toolbox">
                      <li id="obsorinc">

                      </li>
                    </ul>
                    <div class="clearfix"></div>
                  </div>
                  <div class="x_content" id="activeInc" style="height:74.3vh;min-height:70vh;max-height:74.3vh;overflow:auto;">

                    <?php include("Ajax/activeInc.php"); ?>

                  </div>
                </div>
              </div>````

1 Ответ

0 голосов
/ 20 января 2020

Ваш существующий код не требует много изменений для перехода к отправленным на сервер событиям.

На внешнем интерфейсе то, что вы используете в качестве обработчика 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
  }
...