开发者

PHP and Timer events

开发者 https://www.devze.com 2023-02-11 06:21 出处:网络
I would like to use a Timer in php, sending messages after a certain period of time (no player activity)? This is for a multi-player game through sockets.

I would like to use a Timer in php, sending messages after a certain period of time (no player activity)? This is for a multi-player game through sockets.

I have googled and stackoverflew and found the following

  • could use a cron (will need to synroni开发者_Python百科ze my php classes (socket based) with the cron... ), No I guess.
  • could use sleep ... if it could wait for less than one second, I will have given a try, No again, I guess
  • could use register_tick_function ... not applicable I think

Any ideas? Thanks!


This is what I wrote to deal with my timing needs. It doesn't magically interrupt your code, but it provides a very flexible way to schedule timers. All you have to do, is make sure you run $events->CheckTimers() every now and then.

The libevent module does a lot more, but that's a bit more effort.

$events = new Events();

function callback($text) {
        printf("I'm a timer callback %s\n", $text);
}

$events->AddTimer("5s", "callback", "every 5 seconds", EVENTS::EVENT_REPEAT);
$events->AddTimer("2s..15s", "callback", "random time 2 to 15 seconds", EVENTS::EVENT_REPEAT);
$events->AddTimer("1m", create_function('', "echo 'Im a LAMBDA function that runs every minute\n';"), false, EVENTS::EVENT_REPEAT);
$events->AddTimer("1h..2h", "callback", "I will run once, in between 1 and 2 hours");

# This is just an example, in reality, you would make sure to call CheckTimer() regulary (ideally not more than once a second)

while (true) {
        $events->CheckTimers();
        printf("Next timer in %s seconds...\n", $ne = $events->GetNextTimer(), gettype($ne));
        sleep(1);
}


class Events {
    const EVENT_REPEAT      = 0x0001;
    const EVENT_SEQUENCE    = 0x0002;
    var $events;
    var $timers;

    function __construct() {
            $this->events = array();
            $this->timers = array();
    }

    function AddTimer($when, $action, $args = false, $flags = 0) {
            if (preg_match('#([0-9a-zA-Z]+)..([0-9a-zA-Z]+)#', $when, $a)) {
                    $time = time(NULL) + rand($this->time2seconds($a[1]), $this->time2seconds($a[2]));
            } else {
                    $time = time(NULL) + $this->time2seconds($when);
            }
            if ($flags & self::EVENT_SEQUENCE) {
                    while ($this->IsArrayCount($this->timers[$time])) {
                            $time ++;
                    }
            }
            $this->timers[$time][] = array("when" => $when, "action" => $action, "args" => $args, "flags" => $flags);
            ksort($this->timers);
    }

    function GetNextTimer() {
            if (!$this->IsArrayCount($this->timers)) {
                    return false;
            }
            reset($this->timers);
            $firstevent = each($this->timers);
            if ($firstevent === false) {
                    return false;
            }
            $time = $firstevent["key"];
            $nextEvent = $time - time(NULL);
            if ($nextEvent < 1) {
                    return 1;
            }

            return $nextEvent;
    }

    function CheckTimers() {
            $rv = false;
            $now = time(NULL);
            foreach ($this->timers as $time => $events) {
                    if ($time > $now) {
                            break;
                    }
                    foreach ($events as $key => $event) {
                            # debug("Event::CheckTimer: {$event["action"]}");
                            # ircPubMsg("Event::CheckTimer: {$event["action"]}", "#bots");
                            if (!$event["args"]) {
                                    call_user_func($event["action"]);
                            } else {
                                    $rv = call_user_func_array($event["action"], is_array($event["args"]) ? $event["args"] : array($event["args"]));
                            }
                            unset($this->timers[$time][$key]);
                            if ($event["flags"] & self::EVENT_REPEAT) {
                                    $this->AddTimer($event["when"], $event["action"], $event["args"], $event["flags"]);
                            }
                            if ($rv) {
                                    # break;
                            }
                    }
                    if (!$this->IsArrayCount($this->timers[$time])) {
                            unset($this->timers[$time]);
                    }

                    if (0 && $rv) {
                            break;
                    }
            }

            if ($rv) {
                    return $rv;
            }
    }

    function time2seconds($timeString) {
            $end = substr($timeString, strlen($timeString) - 1);
            $seconds = intval($timeString); //  = preg_replace("#[^0-9]#", "", $a);

            if (is_numeric($end)) {
                    return $seconds;
            }

            $unim = array("s","m","h","d", "w", "m", "y");
            $divs = array(1, 60, 60, 24, 7, 28, 12, false);
            $found = false;
            while (!$found) {
                    $u = array_shift($unim);
                    $d = array_shift($divs);
                    $seconds *= $d;
                    if ($end === $u) {
                            return $seconds;
                    }
            }

            return intval($timeString);
    }

    function IsArrayCount($possibleArray) {
            return (isset($possibleArray) && is_array($possibleArray)) ? count($possibleArray) : false;
    }
}


Does PHP's time_nanosleep() work for you? Or usleep()?


Maybe a daemon? http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/


here are a few concepts how to do it : 1. common concept is to create script for sending messages, then add it to server Cron application and execute the script with specified time. 2. write python script that will control your php application file or section, in pythonic terms you can fork process on server start that will do your tasks every amount of time (with infinity loop I guess ... while 1: ..) 3. write shell .sh file that will invoke php or python script and add controls of this script it to /etc/init.d to be more controllable.

0

精彩评论

暂无评论...
验证码 换一张
取 消