如何实现仅能创建1个定时器

WJ825433525

问题描述

我在浏览器中,点击一个按钮a,启动了一个定时器A,我又点击了相同的按钮a,又启动了一个定时器B(定时器A和定时器B是实现相同的功能的),如何实现:点击一个按钮,只能启动一个定时器A,再次点击这个按钮后,无法新建定时器B?代码如下:

   public function onConnect($connection)
    {
        // 定义并执行一个定时器
        $time_interval = 5;// 每5秒执行一次定时器
        // 给connection对象临时添加一个timer_id属性保存定时器id
        $connection->timer_id = Timer::add($time_interval, function () use ($connection) {
            // 连接数据库并时时取出数据
            $id = '1DF22E206ACE919DC47E1A840594CC72';
            $infoMessage = Db::name('message')->find($id);
            $data = $infoMessage['title'];

            // 将数据库数据时时发送给客户端
            $connection->send($data);
            file_put_contents("wangjing.txt", "定时器ID:" . $connection->timer_id . ",时时数据:" . $data . ",当前时间:" . date("y-m-d H:i:s") . "\n", FILE_APPEND | LOCK_EX);
        });
        file_put_contents("wangjing.txt", "定时器ID为:$connection->timer_id\n", FILE_APPEND | LOCK_EX);//有多少个子进程,就会打印多少个定时器ID
    }
459 1 0
1个回答

chaz6chez

用共享内存Apcu或者redis增加一个业务锁,定时器结束时销毁锁;
APCu是血缘关系进程可以共享,redis无限制甚至可以不是一台服务器实例,根据自身情况选择;
当点击按钮时,创建锁并创建定时器,如果创建锁失败了,则忽略;注意在定时器销毁时回收锁;

  • WJ825433525 2023-06-17

    谢谢回答。但是你的方案需要利用其它的技术来实现,我想问:workerman本身能否避免重复创建定时器?

  • chaz6chez 2023-06-17

    目前定时器没有实现,定时器id是自增的,你也可以通过利用workerman的eventloop自行实现定时器,使用静态数组保存timer的id,判断id是否存在

🔝