请问如何实现“定时器添加和删除放在同一个进程”

chroisen

使用GatewayWorker,在Events类中需要实现:

4进程,在一个多用户房间内,服务器设定一个定时器,20秒后取消。但是还剩下15秒的时候,服务器需要取消该定时器。调用Timer::del($timer_id)后仍然会执行。

请问如何实现“定时器添加和删除放在同一个进程”?

场景:

一个房间有6个人,6回合你画我猜。10秒选词,60秒画,5秒答案展示。

10秒选词:
选词开始,设定10秒定时器,告知大家当前回合的题目。如果用户1在5秒的时候选词了,就要清除这个定时器。如果10秒后用户未选词,系统自动选词(定时器内自动清除,这个没问题)

添加定时器后得到timerid 存起来 然后当你收到用户选词的消息后 删除这个timerid。这个方法尝试过吧timerid存在数据库,读取出来清除,但是不成功。

可能过程中,设定定时器和5秒时消除定时器不在一个进程,所以总是清除不成功……

3022 3 1
3个回答

keytehu

定时器里读下数据库里的timeid是否存在,存在的话就运行,不存在就删除自己。
也就是删除定时器改成删除数据库里的timerid

  • 暂无评论
maq

问题的原因应该就是你说的,删除定时器跟创建定时器不在同一个进程。每个进程的 timer id 是各自独立分配的。

可以开一个进程专门用于处理定时器逻辑,所有的 BusinessWorker 跟这个进程通信,发出需要创建、删除定时器的指令(可以用房间号来标识定时器),如果定时器未删除而触发,就通知所有 BusinessWorker 做该做的事。

  • chroisen 2018-02-27

    逻辑是明白的,但是请问可否提供一个“开一个专门的进程处理定时器”的例子呢?非常感激~

maq

@chroisen:大概就是这个样子吧,不知道算不算你想要的例子:

$worker = new Worker("frame://127.0.0.1:1234");
$worker->onMessage = function($connection, $data) {
  $cmd = json_decode($data, true);
  if ($cmd) {
    Timer::add(...);
  } else if ($cmd) {
    Timer::del(...);
  }
};
年代过于久远,无法发表回答
🔝