PHP调用侦听器脚本以连续运行

PHP调用侦听器脚本以连续运行,php,mysqli,ssh2-exec,Php,Mysqli,Ssh2 Exec,我有一个网站,允许用户选择测试脚本,在提交所需测试后,它将发布到insert.php并: 它将inserts发送一行到MySQL数据库中,该行位于with done=0(insert.php)中 有一个监听器脚本(testexe.php),我想在Web服务器上持续运行(可能需要睡眠10秒),每当有done=0的行时,都要监听它,执行它们,然后更改done=1,然后转到下一行 我让这个脚本在while循环中运行,但是,我有一个问题,这个php脚本最初如何被调用?或者我如何激活它以开始?在提交测试之

我有一个网站,允许用户选择测试脚本,在提交所需测试后,它将发布到insert.php并:

  • 它将inserts发送一行到MySQL数据库中,该行位于with done=0(insert.php)中

  • 有一个监听器脚本(testexe.php),我想在Web服务器上持续运行(可能需要睡眠10秒),每当有done=0的行时,都要监听它,执行它们,然后更改done=1,然后转到下一行

  • 我让这个脚本在while循环中运行,但是,我有一个问题,这个php脚本最初如何被调用?或者我如何激活它以开始?在提交测试之前,我是否必须先在服务器上像
    php testexe.php
    那样运行它?因为我知道这个脚本只监听事件,在我的例子中,事件完成=0,但是我如何保持这个脚本一直运行(系统启动)?我不太明白这个部分

    我之所以想这样做,是因为可能有多个用户同时发送请求,所以我想确保他们逐个处理测试并将其排队

    testexe.php

    <?php
    
    ...
    ...    
    
    //while there are still jobs that are not done..
    while (1) {
        //wait for 10 seconds and query again...
        sleep(10);
        $statusResult = mysqli_query($dbConnection, $qStatus);
        //if there are undone jobs we pick them and execute them
        if (mysqli_num_rows($statusResult) > 0){
            //query the next undone test case
            $testResult = mysqli_query($dbConnection, $qNextTest);
    
            //fetch the returned query object and store needed parameters 
            $row = $testResult->fetch_assoc();
            $id = $row['id'];               
            $test_script = $row['test_script']; 
            $gateway = $row['gateway'];         
    
    
            if ($connection = @ssh2_connect($gateway, 22)) {
                ssh2_auth_password($connection, $user, $password);
    
                //execute the test case
                $stream = ssh2_exec($connection, "/my/path/to/script.sh"); 
    
                //fetch output stream and stderr
                stream_set_blocking($stream, true);
                $stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);
                $stream_err = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
                while($line = fgets($stream_out)) {flush(); echo '<pre>' . $line . '</pre>';}               
                echo '<pre>' . "------------------------\n" . '</pre>';
                while($line = fgets($stream_err)) {flush(); echo '<pre>' . $line . '</pre>';}
                fclose($stream);    
    
                //update the table after the above script is done
                $qUpdateStatus = "UPDATE table SET status = 1 WHERE id = $id";
                $updateresult = mysqli_query($dbConnection, $qUpdateStatus);
            }
    
        }
    }
    
    ?>
    
    
    
    我可以想到两个选项:(1)在Web服务器上创建一个cron作业,每5分钟调用一次testexe.php,或者(2)让POST执行testexe.php脚本,并警告testexe.php检查testexe.php的另一个实例当前是否正在运行。

    如果您使用Linux
    cron
    ,可能适合您:

    将此行添加到crontab文件(通过
    crontab-e
    访问)

    然后删除while循环和sleep语句


    如果您需要10秒以外的时间,本页可能会帮助您:

    我明白您的意思,但请快速提问,如果我使用crontab并将其设置为每分钟运行一次(删除while循环和sleep)。如果我的MySQL数据库中有两个“撤消”测试,当它处理第一个“撤消”测试时(假设它需要5分钟),一分钟后它将处理第二个测试,对吗?但这将在服务器上创建一个负载,我希望第一个作业在点击
    fclose($stream)
    并将done设置为1时基本完成,然后继续第二个作业。可能吗?或者我需要在我的代码中添加更多的检查来查找它吗?@kkmoslehpour,您好,也许您可以添加一个
    进行中
    标志(例如,done=0未完成,done=1进行中,done=2完成),并在一个任务设置了此标志时停止脚本。这也是我的想法,让我考虑一下,并相应地更新我的代码,也许以后再听听你的意见。谢谢你。谢谢你的回答,我在上面问了Paul一个问题,也许你也可以帮我回答这个问题。当然-关于服务器上的负载,你是对的。也就是说,您可以同时运行多个testexe.php进程,因为cron每分钟启动一个进程。解决这个问题的方法是让testexe.php首先做两件事:(1)检查是否设置了一个标志来指示另一个testexe.php进程是否正在运行(2)如果另一个进程正在运行,退出;如果不是,则将标志设置为true,然后在done=0的位置处理记录(完成后,将标志设置为false)。“标志”的一种简单类型是简单地创建一个目录。如果directory exists标志为true,如果不是,则标志为false。创建目录会比查询mysql数据库“done”标志快得多吗?您描述的方式是testexe将顺序处理数据库中的每一行,其中done=0。如果testexe只是检查db done标志以确定它是否应该执行,那么您可以让多个testexe进程并行运行。如果可以的话,当然,检查完成标志会起作用。。。
    
    10   *   *   *   *   php testexe.php