咱們通常處理比較常規的定時任務都會用 Linux 系統自帶的定時器 crontab 來執行,可是有時候會知足不了咱們的業務需求,達不到毫秒級別,不過Swoole能夠幫咱們實現。php
咱們看Swoole官方文檔入門指引->快速起步->設置定時器html
swoole提供了相似JavaScript的setInterval/setTimeout異步高精度定時器,粒度爲毫秒級。使用也很是簡單。web
swoole_timer_tick
函數就至關於setInterval,是持續觸發的swoole_timer_after
函數至關於setTimeout,僅在約定的時間觸發一次swoole_timer_tick
和swoole_timer_after
函數會返回一個整數,表示定時器的ID能夠使用 swoole_timer_clear 清除此定時器,參數爲定時器ID瀏覽器
ws_timer.php服務器
<?php /** * WS 優化基礎類庫 */ class Ws { public $ws = null; CONST HOST = "0.0.0.0"; CONST PORT = 80; public function __construct() { // static::HOST, static::PORT $this->ws = new swoole_websocket_server("0.0.0.0", 80); $this->ws->set( [ 'enable_static_handler' => true, // 靜態資源相關設置 'document_root' => "/work/study/code/swoole/demo/static", // 存放靜態資源路徑 // 'worker_num' => 2, // 'task_worker_num' => 2, ] ); $this->ws->on("open", [$this, "onOpen"]); $this->ws->on("message", [$this, "onMessage"]); // $this->ws->on("task", [$this, "onTask"]); // $this->ws->on("finish", [$this, "onFinish"]); $this->ws->on("close", [$this, "onClose"]); $this->ws->start(); } /** * 監聽ws鏈接事件 * @param $ws * @param $request */ public function onOpen($ws, $request) { print_r("Open:" . $request->fd ."\n"); // 使用定時任務 if($request->fd == 1) { // 每2秒執行 swoole_timer_tick(2000, function($timer_id){ echo "2s:timerId:{$timer_id}"; }); } } /** * 監聽ws鏈接消息 * @param $ws * @param $frame */ public function onMessage($ws, $frame) { echo "ser-push-message:{$frame->data}\n"; // TODO::加入咱們這個業務須要執行超過 10s,因此,這裏能夠使用task異步來處理 $data = [ 'task' => 1, 'fd' => $frame->fd, ]; // 投遞一個任務 // $ws->task($data); // 定時任務,5s後執行,這裏是異步任務,不會阻塞,這裏使用閉包 swoole_timer_after(5000, function() use ($ws, $frame){ echo "5s-after\n"; $ws->push($frame->fd, "server-time-after"); }); $ws->push($frame->fd, "server-push:".date("Y-m-d H:i:s")); } /** * 投遞任務 * * @param $serv * @param $taskId * @param $workerId * @param $data */ public function onTask($serv, $task_id, $from_id, $data) { // 耗時場景 10s sleep(10); return "on task finish"; // 告訴worker } public function onFinish($serv, $task_id, $data) { echo "taskId:{$task_id}\n"; // 注意:此$data參數爲onTask方法返回的結果:on task finish,而不是onTask方法的參數。 echo "finish-data-success:{$data}\n"; } /** * 監聽WebSocket鏈接關閉事件 * * @param $ws * @param $fd */ public function onClose($ws, $fd) { echo "clientid-{$fd} is closed \n"; } } $ws_obj = new Ws();
在服務器端執行該腳本:websocket
root@5ee6bfcc1310:/work/study/code/swoole/demo/server# php ws_timer.php Open:3 ser-push-message:Hello-Lily clientid-1 is closed 5s-after clientid-2 is closed
在瀏覽器執行客戶端代碼:ws_task_client.htmlswoole
咱們能夠看到,打開瀏覽器後,等5秒後,服務器經過定時任務會將 server-time-after
信息推到客戶端。閉包