Timer毫秒级定时器

1、基于Reactor线程(在Task worker中使用系统定时器)

2、基于epoll的timeout机制实现

Timer使用

swoole_timer_tick(int $ms,mixed $callback,mixed $param=null);
永久级别定时器
swoole_timer_after(int $ms,mixed $callback);
一次性定时器

代码示例

<?php
class Server
{
    private $serv;
    public $pdo;

    public function __construct() {
        $this->serv = new swoole_server("0.0.0.0", 9501);
        $this->serv->set(array(
            'worker_num' => 3,
            'task_worker_num'=>3,
            'daemonize' => false,
            'max_request' => 10000,
            'dispatch_mode' => 2,
//            'debug_mode'=> 0,

        ));

        $this->serv->on('Start', array($this, 'onStart'));
        $this->serv->on('Connect', array($this, 'onConnect'));
        $this->serv->on('Receive', array($this, 'onReceive'));
        $this->serv->on('Close', array($this, 'onClose'));

        $this->serv->on('WorkerStart', array($this, 'onWorkerStart'));

        $this->serv->on('Task',array($this,'onTask'));
        $this->serv->on('Finish',array($this,'onFinish'));

        $this->serv->start();
    }

    public function onStart( $serv ) {
        echo "Start\n";
    }

    public function onConnect( $serv, $fd, $from_id ) {
//        $serv->send( $fd, "Hello {$fd}!" );
        echo "client {$fd} Connect\n";
    }

    //task回调会在worker进程创建之初调用 不会区分是worker进程还是taskworker进程
    public function onWorkerStart($serv,$worker_id)
    {
        if($worker_id==0){
            swoole_timer_tick(1000,function($timer_id,$params){
                echo  "timer running\n";
                echo "recv:  {$params}\n";
            },'hello');
        }
    }

    //收到客户端的请求
    public function onReceive( swoole_server $serv, $fd, $from_id, $data ) {
        echo "GET Message From Client {$fd}:{$data}";
        swoole_timer_after(1000,function()use($serv,$fd){
            echo "timer after\n";
            $serv->send($fd,'Hello later\n');
        });
        echo "Contimue Handler worker\n";


    }

    public function onTask($serv,$task_id,$from_id,$data)
    {
        return '完成了';
    }

    public function onFinish($serv,$task_id,$data){
        echo "Task {$task_id} finish\n";
        echo "Result:{$data}  \n";

    }

    public function onClose( $serv, $fd, $from_id ) {
        echo "Client {$fd} close connection\n";
    }
}

// 启动服务器
$server = new Server();

第二重方式服务器端代码

<?php
class Server
{
    private $serv;
    private $timer_id;
    private $test;


    public function __construct() {
        $this->serv = new swoole_server("0.0.0.0", 9501);
        $this->serv->set(array(
            'worker_num' => 3,
            'task_worker_num'=>3,
            'daemonize' => false,
            'max_request' => 10000,
            'dispatch_mode' => 2,
//            'debug_mode'=> 0,

        ));

        $this->serv->on('Start', array($this, 'onStart'));
        $this->serv->on('Connect', array($this, 'onConnect'));
        $this->serv->on('Receive', array($this, 'onReceive'));
        $this->serv->on('Close', array($this, 'onClose'));

        $this->serv->on('WorkerStart', array($this, 'onWorkerStart'));

        $this->serv->on('Task',array($this,'onTask'));
        $this->serv->on('Finish',array($this,'onFinish'));

        $this->serv->start();
    }

    public function onStart( $serv ) {
        echo "Start\n";
    }

    public function onConnect( $serv, $fd, $from_id ) {
//        $serv->send( $fd, "Hello {$fd}!" );
        echo "client {$fd} Connect\n";
    }

    //task回调会在worker进程创建之初调用 不会区分是worker进程还是taskworker进程
    public function onWorkerStart($serv,$worker_id)
    {
        if($worker_id==0){
//            swoole_timer_tick(1000,function($timer_id,$params){
//                echo  "timer running\n";
//                echo "recv:  {$params}\n";
//            },'hello');
            $this->test=new test();
            $this->test->index=2;
            swoole_timer_tick(1000,array($this,'onTick'),'hi~!');
        }
    }

    //收到客户端的请求
    public function onReceive( swoole_server $serv, $fd, $from_id, $data ) {
        echo "GET Message From Client {$fd}:{$data}";
        swoole_timer_after(1000,function()use($serv,$fd){
            echo "timer after\n";
            $serv->send($fd,'Hello later\n');
        });
        echo "Contimue Handler worker\n";


    }

    public function onTask($serv,$task_id,$from_id,$data)
    {
        return '完成了';
    }

    public function onFinish($serv,$task_id,$data){
        echo "Task {$task_id} finish\n";
        echo "Result:{$data}  \n";

    }

    public function onTick($timer_id,$params=null)
    {
        echo "params:  {$params}\n";
        echo "Timer {$timer_id} running\n";
        echo  "timer running\n";

        var_dump($this->test);

    }

    public function onClose( $serv, $fd, $from_id ) {
        echo "Client {$fd} close connection\n";
    }
}

class test{
    public $index=0;
}

// 启动服务器
$server = new Server();

客户端

<?php
class Client
{
    private $client;

    public function __construct() {
        $this->client = new swoole_client(SWOOLE_SOCK_TCP);
    }

    public function connect() {
        if( !$this->client->connect("127.0.0.1", 9501 , 1) ) {
            echo "Error:链接失败\n";
        }

        fwrite(STDOUT, "请输入消息:");
        $msg = trim(fgets(STDIN));
        $this->client->send( $msg );
        sleep(1);
        $message = $this->client->recv();
        echo "Get Message From Server:{$message}\n";
    }
}

$client = new Client();
$client->connect();

timer-常见问题

1、timer传递参数

可以通过tick方法的第三个参数传递,也可以使用use闭包

2、timer传递对象

onTimer是在调用tick 方法的进程中回调、因此可以直接使用的worker进程中声明对象(局部变量无法访问)。

3、Timer的清除

Tick方法会返回timer_id,可以使用swoole_timer_clear清除指定的定时器

Last modification:January 26, 2020
如果觉得我的文章对你有用,请随意赞赏