# 毫秒级定时器

Libevent支持文件描述符、信号、定时器三种事件对象，beyod对其进行了封装，使之有一致的调用接口。

beyod使用libevent实际毫秒级定时器，一般来说，常用的定时器有两种：一次性定时器、重复定时器，beyod支持这两种定时器：

一次性定时器：

    $timerid = \Yii::$app->eventLooper->addTimemout($interval, $callback, $arg);

重复定时器：

    $timerid = \Yii::$app->eventLooper->addInterval($interval, $callback, $arg);

$interval
定时器的间隔，单位为毫秒。
$callback 要执行的回调函数， 参数签名为：

    /**
    * @param int $timerid 创建的定时器id
    * @param int $interval 定义定时器时的毫秒间隔
    * @param int $flag  \beyoio\event\EventLooper::EV_TIMEOUT | \beyoio\event\EventLooper::EV_INTERVAL 定时器类型
    * @param mixed $arg 创建定时器时的传递的额外参数
    */
    function($timerid, $interval, $flag, $arg){

    }

定时器的取消

    \Yii::$app->eventLooper->delTimeout($timerid); //取消已经定义的一次性定时器
    \Yii::$app->eventLooper->delInterval($timerid); //取消重复定时器

一次性定时器在激活运行后，相关的资源自动被删除，无须调用者手工清理。

重复定时器会周期性执行，一旦运行后，必须由调用者负责资源清理，否则可能造成内存泄露。

如Listener的空闲连接自动清理逻辑, 就使用了定时器：

    public function keepaliveProbe() {
            if($this->keepalive_interval <=0 || $this->keepalive_timeout <=0){
                return ;
            }

            $this->keepalive_timer = Yii::$app->eventLooper->addInterval($this->keepalive_interval*1000, function($timerId, $interval, $flag, $args=null){
                $now = microtime(true);
                Yii::debug("keepalive probing ...", 'beyoio');
                foreach($this->connections as $id =>$conn){
                    if($conn->request_at >0 && $conn->request_at < ($now - $this->keepalive_timeout)){
                        Yii::debug($conn." keepalive timed out,close it",'beyoio');
                        $conn->close();
                    }
                }
            });
        }