怎么在定时器内部关闭自身定时器?

lichao

问题:
我发送一个信息,要求在明天中午12:00点,发给所有在线用户,然后关闭此定时器。,

我的实现:

$time_interval =60;
\Workerman\Lib\Timer::add($time_interval, function($info,$onlinetime)
{
    if(time()>=$onlinetime)
    {
        $info=json_encode($info);
        Gateway::sendToAll($info);

        (在这里怎***_么_关闭这个定时器)

                }else
    {

        echo '时间未到';
    }

},array($info,$onlinetime));
5056 3 0
3个回答

walkor
global $timer_id;
$time_interval =60;
$timer_id = \Workerman\Lib\Timer::add($time_interval, function($info,$onlinetime)
{
    if(time()>=$onlinetime)
    {
        $info=json_encode($info);
        Gateway::sendToAll($info);
        global $timer_id;
        \Workerman\Lib\Timer::del($timer_id);
    }
    else
    {
        echo '时间未到';
    }
},array($info,$onlinetime));

或者这样也行


$time_interval =60;
$timer_id = \Workerman\Lib\Timer::add($time_interval, function($info,$onlinetime)use(&$timer_id)
{
    if(time()>=$onlinetime)
    {
        $info=json_encode($info);
        Gateway::sendToAll($info);
        \Workerman\Lib\Timer::del($timer_id);
    }
    else
    {
        echo '时间未到';
    }
},array($info,$onlinetime));
  • lichao 2015-10-03

    讲解的很清晰,一看就明白 了,谢谢。

  • fdream 2015-10-24

    第二个写法不行的吧

fdream

第一种方式在有多个计时器的时候会不会引起问题?
第二种方式亲测不行,debug模式下会报 Undefined variable 错误。
我的解决方式是模拟js的写法,每次添加一个非永久计时器,然后在内部如果满足某些条件则直接return,否则继续添加这个计时器。

$timer_func = function($some_var, $timer_func) {
  if (/_something_/) return;
  //do something
  \Workerman\Lib\Timer::add(10, $timer_func, , false);
};
\Workerman\Lib\Timer::add(10, $timer_func, , false);

大概就是这种写法,经过测试是没问题的

  • 暂无评论
walkor

@fdream
第一种多个定时器会有问题,全局变量timer_id会被覆盖
第二种肯定没问题,注意use里面$timer_id前有个引用&
定时器内销毁当前定时器可以参考手册 Timer::add 中实例7 实例8
http://doc.workerman.net/timer/add.html

  • 暂无评论
年代过于久远,无法发表回答
🔝