我poll在Laravel 5.7服务器上有一个API路由,api用户可以在上次轮询后请求任何信息.
如果有新信息,最简单的方法是立即响应有效请求 return $this->prepareResult($newData);
如果没有新数据,我在数据库中存储轮询请求,然后cron实用程序可以每分钟检查一次所有轮询请求,并响应任何已更新数据的轮询.或者,我可以为数据更新创建一个事件监听器,并在更新数据时触发对轮询的响应.
我坚持如何恢复每个会话以匹配等待更新的设备.我可以存储或传递会话ID但是如何确保CRON任务/事件处理器能够响应正确的IP地址,就像它是原始请求一样.php甚至可以这样做吗?
我试图避免websockets,因为有很多设备,但有限的更新/交互.
长轮询是一种有效的技术。我认为用会话运行民意调查是一个坏主意。因为会话仅适用于原始用户。您可以使用 php cli 运行长轮询。您可以检查您的中间件以仅允许 cli 进行路由轮询。您可以使用pthreads 通过 cli 使用 pthreads 来运行长轮询。现在,除了 CLI 之外,pthreads v3 的设计是安全且合理的。您可以使用 cron 每隔一小时触发一次线程。然后在你的控制器中你需要存储一个 $time = time(); 标记您的执行开始时间。然后创建 dowhile 循环来循环轮询过程。while 条件可以是 ($time > time()+3600) 或其他条件。在循环内您需要检查 poll 是否存在?如果为真则运行它。然后在循环内的行底部,您需要休眠一秒钟,例如 2 秒。
在你的background.php(这个文件由cron执行)
<?php
error_reporting(-1);
ini_set('display_errors', 1);
class Atomic extends Threaded {
public function __construct($data = NULL) {
$this->data = $data;
}
private $data;
private $method;
private $class;
private $config;
}
class Task extends Thread {
public function __construct(Atomic $atomic) {
$this->atomic = $atomic;
}
public function run() {
$this->atomic->synchronized(function($atomic)
{
chdir($atomic->config['root']);
$exec_statement = array(
"php7.2.7",
$atomic->config['index'],
$atomic->class,
$atomic->method
);
echo "Running Command".PHP_EOL. implode(" ", $exec_statement)." at: ".date("Y-m-d H:i:s").PHP_EOL;
$data = shell_exec(implode(" ", $exec_statement));
echo $data.PHP_EOL;
}, $this->atomic);
}
private $atomic;
}
$config = array(
"root" => "/var/www/api.example.com/api/v1.1",
"index" => "index.php",
"interval_execution_time" => 200
);
chdir($config['root']);
$threads = array();
$list_threads = array(
array(
"class" => "Background_workers",
"method" => "send_email",
"total_thread" => 2
),
array(
"class" => "Background_workers",
"method" => "updating_data_user",
"total_thread" => 2
),
array(
"class" => "Background_workers",
"method" => "sending_fcm_broadcast",
"total_thread" => 2
)
);
for ($i=0; $i < count($list_threads); $i++)
{
$total_thread = $list_threads[$i]['total_thread'];
for ($j=0; $j < $total_thread; $j++)
{
$atomic = new Atomic();
$atomic->class = $list_threads[$i]['class'];
$atomic->method = $list_threads[$i]['method'];
$atomic->thread_number = $j;
$atomic->config = $config;
$threads[] = new Task($atomic);
}
}
foreach ($threads as $thread) {
$thread->start();
usleep(200);
}
foreach ($threads as $thread)
$thread->join();
?>
Run Code Online (Sandbox Code Playgroud)
这在你的控制器上
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Background_workers extends MX_Controller {
public function __construct()
{
parent::__construct();
$this->load->database();
$this->output->enable_profiler(FALSE);
$this->configuration = $this->config->item("configuration_background_worker_module");
}
public function sending_fcm_broadcast() {
$time_run = time();
$time_stop = strtotime("+1 hour");
do{
$time_run = time();
modules::run("Background_worker_module/sending_fcm_broadcast", $this->configuration["fcm_broadcast"]["limit"]);
sleep(2);
}
while ($time_run < $time_stop);
}
}
Run Code Online (Sandbox Code Playgroud)
这是来自 codeigniter 控制器的示例运行代码。