🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
在日常项目开发中定时任务是很常见的,我们在开发电商业务中抢购秒杀,拍卖等功能模块,例如:拍下订单后在30分钟后自动取消未付款的订单同时把库存加回去。 通常我们会使用 crontab,但是 crontab 的精度不够,最小单位是每分钟。Swoole 就为我提供高精度毫秒的定时器。 PHP 本身的 pcntl_alarm 虽然也提供了类似的实现,但是 pcntl_alarm 最小单位只是秒,而 Swoole 是提供毫秒。而且 pcntl_alarm 不支持同时设定多个定时器程序,并且不支持异步IO。 接下来我们演示使用 ThinkPHP5 和 Swoole 的 swoole_timer_tick 函数来演示毫秒定时器。 创建 ThinkPHP5 自定义命令行 1.创建命令行类 - 创建application/console/Timer.php文件 ~~~ <?php namespace app\Console; use think\console\Command; use think\console\Input; use think\console\Output; class Timer extends Command { protected $server; // 命令行配置函数 protected function configure() { // setName 设置命令行名称 // setDescription 设置命令行描述 $this->setName('timer:start')->setDescription('Start TCP(Timer) Server!'); } // 设置命令返回信息 protected function execute(Input $input, Output $output) { $this->server = new \swoole_server('0.0.0.0', 9501); $this->server->set([ 'worker_num' => 4, 'daemonize' => false, ]); $this->server->on('Start', [$this, 'onStart']); $this->server->on('WorkerStart', [$this, 'onWorkerStart']); $this->server->on('Connect', [$this, 'onConnect']); $this->server->on('Receive', [$this, 'onReceive']); $this->server->on('Close', [$this, 'onClose']); $this->server->start(); // $output->writeln("TCP: Start.\n"); } // 主进程启动时回调函数 public function onStart(\swoole_server $server) { echo "Start" . PHP_EOL; } // Worker 进程启动时回调函数 public function onWorkerStart(\swoole_server $server, $worker_id) { // 仅在第一个 Worker 进程启动时启动 Timer 定时器 if ($worker_id == 0) { // 启动 Timer,每 1000 毫秒回调一次 onTick 函数, swoole_timer_tick(1000, [$this, 'onTick']); } } // 定时任务函数 public function onTick($timer_id, $params = null) { echo 'Hello' . PHP_EOL; } // 建立连接时回调函数 public function onConnect(\swoole_server $server, $fd, $from_id) { echo "Connect" . PHP_EOL; } // 收到信息时回调函数 public function onReceive(\swoole_server $server, $fd, $from_id, $data) { echo "message: {$data} form Client: {$fd}" . PHP_EOL; // 将受到的客户端消息再返回给客户端 $server->send($fd, "Message form Server: ".$data); } // 关闭连时回调函数 public function onClose(\swoole_server $server, $fd, $from_id) { echo "Close" . PHP_EOL; } } ~~~ 2.修改配置文件 - 文件所在 application/command.php ~~~ <?php return [ 'app\console\Timer', ]; ~~~ 接下来就可以通过命令行来启动毫秒定时器 $ > `php think timer:start` 我们会看到以下返回结果 ![](https://box.kancloud.cn/457a2b05f65f0b692b2828b81c2a12f6_714x144.png) 当程序运行后,首次回调 onStart 函数输出 Start,之后每 1000毫秒(每秒),输出一次Hello,就完成了我们的毫秒定时器