add

int \Workerman\Timer::add(float $time_interval, callable $callback [,$args = array(), bool $persistent = true])

Executa uma função ou método de classe em intervalos regulares.

Atenção: O temporizador é executado no processo atual, e o Workerman não criará novos processos ou threads para executar o temporizador.

Parâmetros

time_interval

O intervalo de tempo em que a função deve ser executada, em segundos, suportando números decimais. Pode ser preciso até 0.001, ou seja, a nível de milissegundos.

callback

Função de callback Atenção: se a função de callback for um método de classe, o método deve ser público

args

Parâmetros da função de callback, que devem ser um array, com os elementos do array como valores dos parâmetros.

persistent

Se é persistente ou não. Se você deseja que a função seja executada apenas uma vez, passe false (tarefas que são executadas apenas uma vez serão automaticamente destruídas após a conclusão, não sendo necessário chamar Timer::del()). O padrão é true, ou seja, executar continuamente em intervalo.

Valor de Retorno

Retorna um inteiro que representa o timerid do temporizador, que pode ser destruído chamando Timer::del($timerid).

Exemplo

1. Função temporizada como uma função anônima (closure)

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

$task = new Worker();
// Define quantos processos executarão a tarefa temporizada, atenção para problemas de concorrência em múltiplos processos
$task->count = 1;
$task->onWorkerStart = function(Worker $task)
{
    // Executa a cada 2,5 segundos
    $time_interval = 2.5;
    Timer::add($time_interval, function()
    {
        echo "task run\n";
    });
};

// Executa o worker
Worker::runAll();

2. Configurar o temporizador apenas no processo especificado

Uma instância de worker possui 4 processos, configurando o temporizador apenas no processo com id 0.

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker();
$worker->count = 4;
$worker->onWorkerStart = function(Worker $worker)
{
    // Configura o temporizador apenas no processo com id 0; os processos 1, 2 e 3 não terão temporizadores
    if($worker->id === 0)
    {
        Timer::add(1, function(){
            echo "4 processos de worker, apenas no processo 0 o temporizador é configurado\n";
        });
    }
};
// Executa o worker
Worker::runAll();

3. Função temporizada como uma função anônima, passando parâmetros com closure

use Workerman\Worker;
use Workerman\Timer;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$ws_worker = new Worker('websocket://0.0.0.0:8080');
$ws_worker->count = 8;
// Configura o temporizador quando a conexão é estabelecida
$ws_worker->onConnect = function(TcpConnection $connection)
{
    // Executa a cada 10 segundos
    $time_interval = 10;
    $connect_time = time();
    // Adiciona temporariamente um atributo timer_id ao objeto connection para armazenar o id do temporizador
    $connection->timer_id = Timer::add($time_interval, function()use($connection, $connect_time)
    {
         $connection->send($connect_time);
    });
};
// Quando a conexão é fechada, remove o temporizador correspondente
$ws_worker->onClose = function(TcpConnection $connection)
{
    // Remove o temporizador
    Timer::del($connection->timer_id);
};

// Executa o worker
Worker::runAll();

4. Função temporizada como uma função anônima, passando parâmetros usando a interface do temporizador

use Workerman\Worker;
use Workerman\Timer;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$ws_worker = new Worker('websocket://0.0.0.0:8080');
$ws_worker->count = 8;
// Configura o temporizador quando a conexão é estabelecida
$ws_worker->onConnect = function(TcpConnection $connection)
{
    // Executa a cada 10 segundos
    $time_interval = 10;
    $connect_time = time();
    // Adiciona temporariamente um atributo timer_id ao objeto connection para armazenar o id do temporizador
    $connection->timer_id = Timer::add($time_interval, function($connection, $connect_time)
    {
         $connection->send($connect_time);
    }, array($connection, $connect_time));
};
// Quando a conexão é fechada, remove o temporizador correspondente
$ws_worker->onClose = function(TcpConnection $connection)
{
    // Remove o temporizador
    Timer::del($connection->timer_id);
};

// Executa o worker
Worker::runAll();

5. Função temporizada como uma função comum

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

// Função comum
function send_mail($to, $content)
{
    echo "send mail ...\n";
}

$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
    $to = 'workerman@workerman.net';
    $content = 'hello workerman';
    // Executa a tarefa de enviar e-mail após 10 segundos, passando false como último parâmetro, que indica que deve ser executada apenas uma vez
    Timer::add(10, 'send_mail', array($to, $content), false);
};

// Executa o worker
Worker::runAll();

6. Função temporizada como um método de classe

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

class Mail
{
    // Atenção, a propriedade da função de callback deve ser pública
    public function send($to, $content)
    {
        echo "send mail ...\n";
    }
}

$task = new Worker();
$task->onWorkerStart = function($task)
{
    // Envia uma vez após 10 segundos
    $mail = new Mail();
    $to = 'workerman@workerman.net';
    $content = 'hello workerman';
    Timer::add(10, array($mail, 'send'), array($to, $content), false);
};

// Executa o worker
Worker::runAll();

7. Função temporizada como método de classe (usando temporizador dentro da classe)

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

class Mail
{
    // Atenção, a propriedade da função de callback deve ser pública
    public function send($to, $content)
    {
        echo "send mail ...\n";
    }

    public function sendLater($to, $content)
    {
        // Se o método de callback pertence à classe atual, o primeiro elemento do array de callback será $this
        Timer::add(10, array($this, 'send'), array($to, $content), false);
    }
}

$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
    // Envia uma vez após 10 segundos
    $mail = new Mail();
    $to = 'workerman@workerman.net';
    $content = 'hello workerman';
    $mail->sendLater($to, $content);
};

// Executa o worker
Worker::runAll();

8. Função temporizada como um método estático de classe

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

class Mail
{
    // Atenção, este é um método estático, a propriedade da função de callback também deve ser pública
    public static function send($to, $content)
    {
        echo "send mail ...\n";
    }
}

$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
    // Envia uma vez após 10 segundos
    $to = 'workerman@workerman.net';
    $content = 'hello workerman';
    // Chama o método estático da classe periodicamente
    Timer::add(10, array('Mail', 'send'), array($to, $content), false);
};

// Executa o worker
Worker::runAll();

9. Função temporizada como um método estático de classe (com namespace)

namespace Task;

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

class Mail
{
    // Atenção, este é um método estático, a propriedade da função de callback também deve ser pública
    public static function send($to, $content)
    {
        echo "send mail ...\n";
    }
}

$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
    // Envia uma vez após 10 segundos
    $to = 'workerman@workerman.net';
    $content = 'hello workerman';
    // Chama o método estático com namespace da classe periodicamente
    Timer::add(10, array('\Task\Mail', 'send'), array($to, $content), false);
};

// Executa o worker
Worker::runAll();

10. Destruir o temporizador atual dentro do temporizador (usando o método use para passar $timer_id)

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
    // Contagem
    $count = 1;
    // Para que $timer_id seja passado corretamente para dentro da função de callback, o $timer_id deve ser precedido pelo símbolo de endereço &
    $timer_id = Timer::add(1, function()use(&$timer_id, &$count)
    {
        echo "Timer run $count\n";
        // Destrói o temporizador após 10 execuções
        if($count++ >= 10)
        {
            echo "Timer::del($timer_id)\n";
            Timer::del($timer_id);
        }
    });
};

// Executa o worker
Worker::runAll();

11. Destruir o temporizador atual dentro do temporizador (passando $timer_id como parâmetro)

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

class Mail
{
    public function send($to, $content, $timer_id)
    {
        // Adiciona temporariamente uma propriedade count ao objeto atual para registrar o número de execuções do temporizador
        $this->count = empty($this->count) ? 1 : $this->count;
        // Destrói o temporizador após 10 execuções
        echo "send mail {$this->count}...\n";
        if($this->count++ >= 10)
        {
            echo "Timer::del($timer_id)\n";
            Timer::del($timer_id);
        }
    }
}

$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
    $mail = new Mail();
    // Para que $timer_id seja passado corretamente para dentro da função de callback, o $timer_id deve ser precedido pelo símbolo de endereço &
    $timer_id = Timer::add(1, array($mail, 'send'), array('to', 'content', &$timer_id));
};

// Executa o worker
Worker::runAll();