使用数组 php Javascript 进行长轮询

Long Polling with an array php Javascript

提问人:DDub 提问时间:7/15/2023 更新时间:7/15/2023 访问量:32

问:

对长轮询非常陌生,刚刚让它工作,但试图让它与数组一起工作。我对 php 方面的理解相当好,但我对 Javascript 很陌生。

active_calls.php

<?php
class Calls {
  // (A) CONSTRUCTOR - CONNECT TO DATABASE
  protected $pdo = null;
  protected $stmt = null;
  function __construct () {
    $this->pdo = new PDO(
      "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET,
      DB_USER, DB_PASSWORD, [
      PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
      PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    ]);
  }

  // (B) DESTRUCTOR - CLOSE CONNECTION
  function __destruct () {
    if ($this->stmt !== null) { $this->stmt = null; }
    if ($this->pdo !== null) { $this->pdo = null; }
  }

  // (C) GET LATEST SCORE
  function getCalls () {
    $this->stmt = $this->pdo->prepare(
      "SELECT *, UNIX_TIMESTAMP(`call_time`) AS `unix`
       FROM `calls` WHERE call_status=1 ORDER BY `call_time` DESC"
    );
    $this->stmt->execute();
    return $this->stmt->fetch();
  }
}

// (D) DATABASE SETTINGS - CHANGE THESE TO YOUR OWN!
define("DB_HOST", "localhost");
define("DB_NAME", "xxxxx");
define("DB_CHARSET", "utf8mb4");
define("DB_USER", "xxxxx");
define("DB_PASSWORD", "xxxxx");

// (E) CHECK FOR SCORE UPDATES
if (isset($_POST["last"])) {
  // (E1) SET TIME LIMIT
  set_time_limit(30); // set an appropriate time limit
  ignore_user_abort(false); // stop when long polling breaks

  // (E2) LOOP UNTIL THERE ARE UPDATES OR TIMEOUT
  $_CALL = new Calls();
  while (true) {
    $call = $_CALL->getCalls();
    if (isset($call["unix"]) && $call["unix"] > $_POST["last"]) {
      echo json_encode($call);
      break;
    }
    sleep(1); // short pause to not break server
  }
}

active_call.html

<html>
<head>
  <link rel="stylesheet" href="style/style.css">
  <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
  <meta http-equiv="Pragma" content="no-cache" />
  <meta http-equiv="Expires" content="0" />
</head>

<table>
  <tr>
    <th>Call Time</th>
    <th>Station IP</th>
    <th>Call Status</th>
    <th>Action</th>
  </tr>
  <tr align='center'>
    <td><div id="Time"></div></td>
    <td><div id="StationIP"></div></td>
    <td><div id="CallStatus"></td>
  </tr>
</table>


<script>
// (B) LAST UPDATED TIMESTAMP
var last = 0;

// (C) AJAX LONG POLL
function GetCurrentUnixTimeStamp() {
  return Math.floor(Date.now() / 1000);
}
function poll () {
  // (C1) FORM DATA
  let data = new FormData();
  data.append("last", last);
  console.log("Fetch run", last);

  // (C2) FETCH UPDATE ON SERVER RESPONSE

  fetch("active_calls.php", { method:"POST", body:data })
  .then(res => res.json())
  .then(data => {
    console.log(data);
    // (C2-1) UPDATE HTML DISPLAY

    document.getElementById("Time").innerHTML = GetCurrentUnixTimeStamp() - data.unix;
    document.getElementById("StationIP").innerHTML = data.station_ip;
    document.getElementById("CallStatus").innerHTML = data.call_status;

    // (C2-2) NEXT ROUND
    last = data.unix;
    poll();
  })

  // (C3) CATCH ERROR - LOOP ON TIMEOUT
  .catch(err => poll());
}

// (D) GO!
window.onload = poll;
</script>
</html>

数据样本

call_id call_status call_time station_ip UNIX的
3 1 2023-07-09 11:47:51 192.168.254.200 1688921271
2 1 2023-07-08 21:36:30 192.168.200.201 1688870190

我已经多次尝试声明为数组并将值附加到数组中,但我什至不确定如何在 Javascript 端循环访问数组以在我正确获取数据后将其拉回。看起来这应该很简单,但我已经尝试了几个星期,几年后也刚刚回到 php,所以我有点生疏。

javascript php 长轮询

评论

0赞 ADyson 7/15/2023
您可以在 JS 中使用循环for

答: 暂无答案