云服务器

Swoole入门(4)☞创建毫秒级定时器

2017-12-15 10:24:04 0

crontab服务 VS 基于swoole的定时器

一般开发者都是使用linux自带的crontab定时处理服务,crontab服务够稳定,有日志,基于服务器,非常好用;但是有个缺点就是只支持分钟时间级别的定时器。

而swoole的timer定时器完全可以弥补这个缺点,支持毫秒级的定时器,同时支持异步操作

timer定时器

timer定时器基于Reactor线程,在Worker进程和Task进程使用。

timer定时器基于epoll的timeout机制实现。

timer定时器使用最小堆数据结构存放定时任务,触发时间越短越靠近堆顶,大大提高了检索效率。

示例代码

<?php

class Test { public $index = 0; }

class Server { private $serv; private $test;

public function __construct() {
    $this-&gt;serv = new swoole_server("0.0.0.0", 9501);
    $this-&gt;serv-&gt;set(array(
        'worker_num' =&gt; 8,
        'daemonize' =&gt; false,
        'max_request' =&gt; 10000,
        'dispatch_mode' =&gt; 2,
    ));
    $this-&gt;serv-&gt;on('Start', array($this, 'onStart'));
    $this-&gt;serv-&gt;on('Connect', array($this, 'onConnect'));
    $this-&gt;serv-&gt;on('Receive', array($this, 'onReceive'));
    $this-&gt;serv-&gt;on('Close', array($this, 'onClose'));
    $this-&gt;serv-&gt;on('WorkerStart', array($this, 'onWorkerStart'));

    $this-&gt;serv-&gt;start();
}
public function onStart( $serv ) {
    echo "Start\n";
}
public function onConnect( $serv, $fd, $from_id ) {
    echo "Client {$fd} connect\n";
}
public function onClose( $serv, $fd, $from_id ) {
    echo "Client {$fd} close connection\n";
}

public function onWorkerStart( $serv , $worker_id) {
    if( $worker_id == 0 )
    {
        $this-&gt;test=new Test();
        $this-&gt;test-&gt;index = 1;
        swoole_timer_tick(1000, array($this, 'onTick'), "Hello");
    }
}

public function onReceive( swoole_server $serv, $fd, $from_id, $data ) {
    echo "Get Message From Client {$fd}:{$data}\n";

    echo "Continue Handle Worker\n";
}

public function onTick($timer_id,  $params = null) {
    echo "Timer {$timer_id} running\n";
    echo "Params: {$params}\n";

    echo "Timer running\n";
    echo "recv: {$params}\n";

    var_dump($this-&gt;test);
}

}

$server = new Server();

代码输出

root:/var/www/html/silence/swoole/timer# php timer.php
Start
Timer 1 running
Params: Hello
Timer running
recv: Hello
object(Test)#5 (1) {
  ["index"]=>
  int(1)
}
Timer 1 running
Params: Hello
Timer running
recv: Hello
object(Test)#5 (1) {
  ["index"]=>
  int(1)
}

代码流程

定时器在worker进程启动时就启动,因为不希望每个worker进程都启动该定时器,所以用了workerid进行判断,只在第一个worker进程中启动。

swooletimertick(int $ms, callable $callback, mixed $user_param);

设置一个间隔时钟定时器,该定时器会一直持续触发,直到调用swooletimerclear清除该定时器。

$ms 指定时间,单位为毫秒

$callback_function 时间到期后所执行的函数,必须是可以调用的。

$userparam 可以传一些业务参数, 该参数会被传递到$callbackfunction中. 如果有多个参数可以使用数组形式。

注意:

定时器仅在当前进程空间内有效

定时器是纯异步实现的,不能与阻塞IO的函数(如sleep()函数)一起使用,否则定时器的执行时间会发生错乱

与其相对立的是swooletimerafter()函数,还函数只会调用一次。

onTick($timer_id, $params = null);上文中的定时器异步回调函数是该函数。
$timerid 定时器的ID,可用于swooletimer_clear清除此定时器

$params 由swooletimertick传入的第三个参数

swooletimerclear(int $timer_id)是使用定时器ID来删除定时器。

$timerid,定时器ID,调用swooletimer_tick、swooletimerafter后会返回一个整数的ID

swooletimerclear不能用于清除其他进程的定时器,只作用于当前进程

结语

接下来继续给大家讲讲进程相关知识,同时学习对swoole进程的使用。
 
上一篇: 无

微信关注

获取更多技术咨询