diff --git a/README.md b/README.md index c853315..d964155 100644 --- a/README.md +++ b/README.md @@ -253,7 +253,46 @@ class SessionController extends HttpController 查看事例[session](examples/session/session.php) +#### 任务 +在控制器中使用`$this->task()`, 这个是异步, 想使用同步可以`$this->syncTask()`. + +```php + + ... + public function taskTest() + { + $taskId = $this->task('push all message worker' . $this->workerId, PushTaskHandle::class); + //$status = $this->syncTask('sync push all message', PushTaskHandle::class); + //var_dump($status); + return "task push id:" . $taskId . ", workId:" . $this->workerId; + } + +``` + +查看事例[task](examples/task/task.php) + +#### 全局定时器 + +在有些业务中我们可能会有这样的需求,比如每隔两小时需要读取下订单数.但你也可以用`crontab`实现. +相同时间的定时器会被最后一次添加的定时器覆盖,定时器时间单位为毫秒. + + +```php + +... + +$app->addTicker(100, \Surf\Examples\HeartbeatTicker::class); + +try { + $app->run(); +} catch (\Surf\Exception\ServerNotFoundException $e) { + +} + +``` + +查看事例[ticker](examples/ticker/ticker.php) ## License diff --git a/examples/HeartbeatTicker.php b/examples/HeartbeatTicker.php new file mode 100644 index 0000000..202615d --- /dev/null +++ b/examples/HeartbeatTicker.php @@ -0,0 +1,22 @@ +interval; + } +} \ No newline at end of file diff --git a/examples/client.php b/examples/client.php new file mode 100644 index 0000000..df24f1c --- /dev/null +++ b/examples/client.php @@ -0,0 +1,36 @@ + 'Lpl.Gift', + 'data' => [ + 'propId'=> 10387, + 'uid' => 15, + ], +]; +// 所有参数数据包 +$body = json_encode($body); +$toType = 11000; +$toIp = -1; +$fromType = 0; +$fromIp = 0; +$nowAskId = crc32(uniqid(microtime(), true)); +$askId2 = 0; +$head = pack('IsIsIII', strlen($body), $toType, $toIp, $fromType, $fromIp, $nowAskId, $askId2); +$body = $head . $body; + + +$client = new Client(SWOOLE_SOCK_TCP); +if (!$client->connect('127.0.0.1', 20002, 0.5)) { + exit("connect failed. Error: {$client->errCode}\n"); +} +$client->send($body); +echo $client->recv(); +$client->close(); \ No newline at end of file diff --git a/examples/ticker/ticker.php b/examples/ticker/ticker.php new file mode 100644 index 0000000..2b8b6ff --- /dev/null +++ b/examples/ticker/ticker.php @@ -0,0 +1,28 @@ + $config +]); + +$app->register(new \Surf\Provider\RedisServiceProvider()); + +$app->addTicker(100, \Surf\Examples\HeartbeatTicker::class); + +try { + $app->run(); +} catch (\Surf\Exception\ServerNotFoundException $e) { + +} \ No newline at end of file diff --git a/src/Surf/Application.php b/src/Surf/Application.php index 329d5da..68e0d95 100644 --- a/src/Surf/Application.php +++ b/src/Surf/Application.php @@ -212,6 +212,24 @@ public function addProtocolGroup(string $prefix, callable $callback) return $this; } + /** + * @param int $mill + * @param string $class + * @return $this + */ + public function addTicker(int $mill, string $class) + { + if (!$this->isBoot) { + + /** + * @var $server Server + */ + $server = $this->get('server'); + + $server->addTicker($mill, $class); + } + return $this; + } /** * Start to service * @throws ServerNotFoundException diff --git a/src/Surf/Server/Server.php b/src/Surf/Server/Server.php index e1541bc..0a325ee 100644 --- a/src/Surf/Server/Server.php +++ b/src/Surf/Server/Server.php @@ -12,6 +12,8 @@ use Surf\Cache\Driver\Redis; use Surf\Pool\PoolManager; use Surf\Task\TaskHandle; +use Surf\Ticker\Ticker; +use Surf\Ticker\TickerInterface; use Swoole\Server as SwooleServer; use Surf\Task\TaskHandleInterface; @@ -33,6 +35,11 @@ abstract class Server ], ]; + /** + * 应用名称 + * @var mixed|string + */ + protected $name = 'surf'; /** * @var null|Container */ @@ -43,6 +50,13 @@ abstract class Server */ protected $task = [ + ]; + + /** + * @var array + */ + protected $ticker = [ + ]; /** * Server constructor. @@ -53,6 +67,7 @@ public function __construct(Container $container, array $config = []) { $this->container = $container; $this->defaultConfig = array_merge($this->defaultConfig, $config); + $this->name = $this->defaultConfig['name'] ?? 'surf'; $this->init(); $this->bootstrap(); } @@ -121,7 +136,7 @@ abstract protected function connect(\Swoole\Server $server, int $fd, int $reacto abstract protected function close(\Swoole\Server $server, int $fd, int $reactorId); /** - * + * 启动服务 */ public function run() { @@ -135,7 +150,7 @@ public function run() public function onStart(\Swoole\Server $server) { $this->start($server); - swoole_set_process_name('surf:master'); + swoole_set_process_name($this->name. ':master'); } /** @@ -145,7 +160,7 @@ public function onStart(\Swoole\Server $server) public function onManagerStart(\Swoole\Server $server) { $this->managerStart($server); - swoole_set_process_name('surf:manager'); + swoole_set_process_name($this->name . ':manager'); } /** @@ -163,13 +178,24 @@ public function onWorkerStart(\Swoole\Server $server, int $workerId) $pool = $this->container->get('pool'); $pool && $pool->tick(); } + if ($this->ticker) { + foreach ($this->ticker as $mill => $ticker) { + /** + * @var $ticker Ticker + */ + $ticker->setContainer($this->container); + $ticker->setServer($server); + $ticker->setInterval($mill); + $server->tick($mill, [$ticker, 'execute']); + } + } } $this->workerStart($server, $workerId); $workerNumber = $this->defaultConfig['setting']['worker_num'] ?? 1; if ($workerId >= $workerNumber) { - swoole_set_process_name('surf:task'); + swoole_set_process_name($this->name . ':task'); } else { - swoole_set_process_name('surf:worker'); + swoole_set_process_name($this->name . ':worker'); } } @@ -271,17 +297,33 @@ public function onFinish(SwooleServer $server, int $taskId, $data) $logger = $this->container->get('logger'); $logger->info($message); } else { - $logFile = $this->defaultConfig['setting']['log_file'] ?? '/tmp/swoole.task.log'; - $format = sprintf( - '[%s] INFO: %s', - date('Y-m-d H:i:s'), - $message - ); - file_put_contents($logFile, $format); + $logFile = $this->defaultConfig['setting']['log_file'] ?? '/tmp/'. $this->name .'.log'; + $message = sprintf('[%s] INFO: %s', date('Y-m-d H:i:s'), $message); + error_log($message, 3, $logFile); } } } + /** + * @param int $mill + * @param string $className + * @return bool + */ + public function addTicker(int $mill, string $className) + { + if (!class_exists($className)) { + return false; + } + + $tick = new $className; + if (!($tick instanceof TickerInterface)) { + unset($tick); + return false; + } + $this->ticker[$mill] = $tick; + + return true; + } /** * @return null|SwooleServer */ diff --git a/src/Surf/Ticker/Ticker.php b/src/Surf/Ticker/Ticker.php new file mode 100644 index 0000000..28e90f1 --- /dev/null +++ b/src/Surf/Ticker/Ticker.php @@ -0,0 +1,56 @@ +server = $server; + } + + /** + * @param null|Container $container + */ + public function setContainer(Container $container) + { + $this->container = $container; + } + + /** + * @param int $interval + */ + public function setInterval(int $interval) + { + $this->interval = $interval; + } +} \ No newline at end of file diff --git a/src/Surf/Ticker/TickerInterface.php b/src/Surf/Ticker/TickerInterface.php new file mode 100644 index 0000000..471b5a9 --- /dev/null +++ b/src/Surf/Ticker/TickerInterface.php @@ -0,0 +1,15 @@ +