2

高级想法:我有一个微控制器,可以通过 http 请求连接到我的站点...我想在数据库中记录更改后立即向设备提供响应...

由于终端设备是客户端,即微控制器...我不知道无需设置端口转发即可将数据传递给客户端的方法...这是非常不希望的...尝试发送时出现问题从外部网络到内部网络的数据... A. 端口转发或 B 让客户端设备启动请求,这使我想到让设备向文件发送 http 请求以轮询更改

更新

  • 非常感谢奥利琼斯。我在这里暗示了他的一些建议。

  • Jason McCreary 建议修改列,这是一个很大的改进,因为它应该提高速度和可靠性......好建议!:)

  • 如果在此示例中存在数据库过度工作的问题,
    则以下操作可能会起作用...当数据插入数据库时​​,更改将写入文件...然后有循环
    不断检查该文件是否有更新....想法?

我有table1并且我想查看自上次检查以来是否更新了特定行(基于 UID/键),并且如果记录投注更新,则持续检查 60 秒...

我想我可以使用 INFORMATION_SCHEMA 数据库来做到这一点。

该数据库包含有关表、视图、列等的信息。

尝试解决方案:

    <?php 
$timer = time() + (10);//add 60 seconds
$KEY=$_POST['KEY'];
$done=0;

if(isset($KEY)){
//loign stuff
require_once('Connections/check.php');
$mysqli = mysqli_connect($hostname_check, $username_check, $password_check,$database_check);
if (mysqli_connect_errno($mysqli))
{ echo "Failed to connect to MySQL: " . mysqli_connect_error(); }
//end login


$query = "SELECT data1, data2
FROM station 
WHERE client = $KEY
AND noted = 0;";

$update=" UPDATE station
SET noted=1
WHERE client = $KEY
AND noted = 0;";

while($done==0) {
   $result = mysqli_query($mysqli, $query);
   $update = mysqli_query($mysqli, $update);

   $row_cnt = mysqli_num_rows($result);

   if ($row_cnt > 0) {
      $row = mysqli_fetch_array($result);
      echo  'data1:'.$row['data1'].'/';
      echo  'data2:'.$row['data2'].'/';
      print $row[0];
      $done=1;
   }
   else {
      $current = time();
      if($timer > $current){ $done=0; sleep(1); } //so if I haven't had a result update i want to loop back an check again for 60seconds
   else { $done=1; echo 'done:nochange';}//60seconds pass end loop
}}

mysqli_close($mysqli);
echo 'time:'.time();
}
else {echo 'error:nokey';}
?>

这是提高速度和提高可靠性的适当方法和建议吗

4

2 回答 2

2

如果我正确理解您的应用程序,您的客户端是一个微控制器。它不时向您的 php / mysql Web 应用程序发出 HTTP 请求。该请求的频率取决于微控制器,但似乎是每分钟一次左右。

该请求基本上是问,“伙计,有什么新东西要给我吗?”

您的网络应用程序需要发送答案,“不是现在”或“这就是我所拥有的”。

您的应用程序的另一部分是提供相关信息。它与您的微控制器异步执行此操作(即,只要它愿意)。

使微控制器查询高效是您当前的目标。

(注意,如果我有任何这些假设是错误的,请纠正我。)

您的表格将需要一last_update列、一which_microcontroller列或等价物以及一notified列。只是为了笑,让我们也放入value1value2列。你还没有告诉我们你在表中保留了什么样的数据。

您更新表格的软件需要这样做:

 UPDATE theTable 
   SET notified=0, last_update = now(), 
       value1=?data, 
       value2?=data
 WHERE which_microcontroller = ?microid

它可以根据需要经常执行此操作。新数据值替换并覆盖旧数据值。

您处理微控制器请求的软件需要执行以下查询序列:

  START TRANSACTION;

 SELECT value1, value2
   FROM theTable 
  WHERE notified = 0
    AND microcontroller_id = ?microid
    FOR UPDATE;

 UPDATE theTable
    SET notified=1
  WHERE microcontroller_id = ?microid;

 COMMIT;

如果自上次查询以来已更新,这将从数据库中检索最新的 value1 和 value2 项目(您的应用程序的数据,无论它是什么)。处理来自微控制器的请求的 php 程序可以用该数据进行响应。

如果 SELECT 语句没有返回任何行,您的 php 代码会以“无更改”响应微控制器。

这一切都假设微控制器 ID 是唯一键。如果不是,您仍然可以这样做,但它有点复杂。

注意我们在这个例子中没有使用 last_update。我们只是使用了通知标志。

如果您想等到上次更新后的 60 秒,则可以这样做。也就是说,如果你想等到 value1 和 value2 停止变化,你可以这样做。

  START TRANSACTION;

 SELECT value1, value2
   FROM theTable 
  WHERE notified = 0
    AND last_update <= NOW() - INTERVAL 60 SECOND
    AND microcontroller_id = ?microid
    FOR UPDATE;

 UPDATE theTable
    SET notified=1
  WHERE microcontroller_id = ?microid;

 COMMIT;

为了使这些查询高效,您将需要此索引:

  (microcontroller_id, notified, last_update)

在这种设计中,您不需要让 PHP 代码循环轮询数据库。相反,您在微控制器签入更新时查询数据库/

于 2013-07-29T18:02:22.003 回答
0

如果所有table1更改都由PHP处理,则没有理由轮询数据库。更新时在 PHP 级别添加所需的逻辑table1

例如(假设 OOP):

public function update() {
  if ($row->modified > (time() - 60)) {
    // perform code for modified in last 60 seconds
  }

  // run mysql queries
}
于 2013-07-29T17:34:16.157 回答