From 19e61c7cc31109ef299cbaa6b30bbfbc5f80f91b Mon Sep 17 00:00:00 2001 From: jerry Date: Tue, 16 Mar 2021 01:34:17 +0800 Subject: [PATCH] update to build 386 fix ZM_DATA equals null add containsImage, getImageCQFromLocal function for MessageUtil --- docs/event/framework-annotations.md | 21 ++++++++++++++ docs/guide/basic-config.md | 14 +++++---- docs/update/v2.md | 6 ++++ mkdocs.yml | 14 ++++++--- src/Module/Example/Hello.php | 9 ++++++ src/ZM/ConsoleApplication.php | 6 ++-- src/ZM/Framework.php | 8 ++--- src/ZM/Utils/MessageUtil.php | 45 +++++++++++++++++++++++++++++ src/ZM/Utils/TaskManager.php | 6 ++++ 9 files changed, 112 insertions(+), 17 deletions(-) diff --git a/docs/event/framework-annotations.md b/docs/event/framework-annotations.md index fd251959..874d227d 100644 --- a/docs/event/framework-annotations.md +++ b/docs/event/framework-annotations.md @@ -221,6 +221,27 @@ | tick_ms | `int`,**必填**,间隔的毫秒数,例如 1 秒间隔为 `1000`,范围大于 0,小于 86400000。 | | | | worker_id | `int`,要在哪个 Worker 进程上执行,默认为 0,范围是 0~{你设定的 Worker 数量-1},如果是 -1 的话,则会在所有 Worker 进程上触发。 | 限定只执行的 Worker 进程 | | +## OnTask() + +定义一个在工作进程中运行的任务函数。详情见 [进阶 - 使用 TaskWorker 进程处理密集运算](/advanced/task-worker)。 + +### 属性 + +| 类型 | 值 | +| ---------- | ----------------------------- | +| 名称 | `@OnTask` | +| 触发前提 | 在框架加载后激活 | +| 命名空间 | `ZM\Annotation\Swoole\OnTask` | +| 适用位置 | 方法 | +| 返回值处理 | 有,返回 Worker 进程的结果 | + +### 注解参数 + +| 参数名称 | 参数范围 | 用途 | 默认 | +| --------- | ------------------------------------------------------------ | ------------ | ---- | +| task_name | `string`,**必填**,任务函数的名称,不建议重复。 | | | +| rule | 设置触发前提,PHP 代码,返回 bool 值即可,参考 OnRequestEvent | 限定是否执行 | 空 | + ## OnSetup() 在框架加载前执行的代码。此部分代码是在主进程执行的,不可在此事件中使用任何协程相关的功能。 diff --git a/docs/guide/basic-config.md b/docs/guide/basic-config.md index 449bd6f2..61a32ca6 100644 --- a/docs/guide/basic-config.md +++ b/docs/guide/basic-config.md @@ -36,12 +36,14 @@ ### 子表 **swoole** -| 配置名称 | 说明 | 默认值 | -| --------------- | ------------------------------------------------------------ | ----------------------------------- | -| `log_file` | Swoole 的日志文件 | `crash_dir` 下的 `swoole_error.log` | -| `worker_num` | Worker 工作进程数 | 运行框架的主机 CPU 核心数 | -| `dispatch_mode` | 数据包分发策略,见 [文档](https://wiki.swoole.com/#/server/setting?id=dispatch_mode) | 2 | -| `max_coroutine` | 最大协程并发数 | 300000 | +| 配置名称 | 说明 | 默认值 | +| ----------------------- | ------------------------------------------------------------ | ----------------------------------- | +| `log_file` | Swoole 的日志文件 | `crash_dir` 下的 `swoole_error.log` | +| `worker_num` | Worker 工作进程数 | 运行框架的主机 CPU 核心数 | +| `dispatch_mode` | 数据包分发策略,见 [文档](https://wiki.swoole.com/#/server/setting?id=dispatch_mode) | 2 | +| `max_coroutine` | 最大协程并发数 | 300000 | +| `task_worker_num` | TaskWorker 工作进程数 | 默认不开启(此参数被注释) | +| `task_enable_coroutine` | TaskWorker 工作进程启用协程 | 默认不开启(此参数被注释)或 `bool` | ### 子表 **light_cache** diff --git a/docs/update/v2.md b/docs/update/v2.md index 0e162191..c49fc3e7 100644 --- a/docs/update/v2.md +++ b/docs/update/v2.md @@ -1,5 +1,11 @@ # 更新日志(v2 版本) +## 2.3.0-beta1 + +> 更新时间:2021.3.16 + +- + ## 2.2.11 > 更新时间:2021.3.13 diff --git a/mkdocs.yml b/mkdocs.yml index 9c7613ef..28aee039 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -72,9 +72,12 @@ nav: - 事件分发器: event/event-dispatcher.md - 框架组件: - 框架组件: component/index.md - - 机器人 API: component/robot-api.md - - CQ 码(多媒体消息): component/cqcode.md - 上下文: component/context.md + - 聊天机器人组件: + - 机器人 API: component/robot-api.md + - CQ 码(多媒体消息): component/cqcode.md + - 机器人消息处理: component/message-util.md + - Token 验证: component/access-token.md - 存储: - LightCache 轻量缓存: component/light-cache.md - MySQL 数据库: component/mysql.md @@ -82,13 +85,15 @@ nav: - ZMAtomic 原子计数器: component/atomics.md - SpinLock 自旋锁: component/spin-lock.md - 文件管理: component/data-provider.md + - HTTP 服务器工具类: + - HTTP 和 WebSocket 客户端: component/zmrequest.md + - HTTP 路由管理: component/route-manager.md - 协程池: component/coroutine-pool.md - 单例类: component/singleton-trait.md - ZMUtil 杂项: component/zmutil.md - 全局方法: component/global-functions.md - - HTTP 和 WebSocket 客户端: component/zmrequest.md - Console 终端: component/console.md - - Token 验证: component/access-token.md + - TaskWorker 管理: component/task-worker.md - 进阶开发: - 进阶开发: advanced/index.md - 框架剖析: advanced/framework-structure.md @@ -97,6 +102,7 @@ nav: - 内部类文件手册: advanced/inside-class.md - 接入 WebSocket 客户端: advanced/connect-ws-client.md - 框架多进程: advanced/multi-process.md + - TaskWorker 提高并发: advanced/task-worker.md - 开发实战教程: - 编写管理员才能触发的功能: advanced/example/admin.md - FAQ: FAQ.md diff --git a/src/Module/Example/Hello.php b/src/Module/Example/Hello.php index 3e9ffd91..3e3b496b 100644 --- a/src/Module/Example/Hello.php +++ b/src/Module/Example/Hello.php @@ -6,6 +6,7 @@ use ZM\Annotation\Http\Middleware; use ZM\Annotation\Swoole\OnCloseEvent; use ZM\Annotation\Swoole\OnOpenEvent; use ZM\Annotation\Swoole\OnRequestEvent; +use ZM\Annotation\Swoole\OnStart; use ZM\ConnectionManager\ConnectionObject; use ZM\Console\Console; use ZM\Annotation\CQ\CQCommand; @@ -21,6 +22,14 @@ use ZM\Utils\ZMUtil; */ class Hello { + /* + * 默认的图片监听路由对应目录,如需要使用可取消下面的注释,把上面的 /* 换成 /** + * @OnStart(-1) + */ + //public function onStart() { + // \ZM\Http\RouteManager::addStaticFileRoute("/images/", \ZM\Utils\DataProvider::getWorkingDir()."/zm_data/images/"); + //} + /** * 使用命令 .reload 发给机器人远程重载,注意将 user_id 换成你自己的 QQ * @CQCommand(".reload",user_id=627577391) diff --git a/src/ZM/ConsoleApplication.php b/src/ZM/ConsoleApplication.php index 6ddb62e8..cc542b21 100644 --- a/src/ZM/ConsoleApplication.php +++ b/src/ZM/ConsoleApplication.php @@ -18,8 +18,8 @@ use ZM\Utils\DataProvider; class ConsoleApplication extends Application { - const VERSION_ID = 385; - const VERSION = "2.3.0"; + const VERSION_ID = 386; + const VERSION = "2.3.0-beta1"; public function __construct(string $name = 'UNKNOWN') { define("ZM_VERSION_ID", self::VERSION_ID); @@ -54,7 +54,7 @@ class ConsoleApplication extends Application $composer["autoload"]["psr-4"]["Custom\\"] = "src/Custom"; $r = file_put_contents(DataProvider::getWorkingDir() . "/composer.json", json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); if ($r !== false) { - echo "成功添加!请重新进行 composer update !\n"; + echo "成功添加!请运行 composer dump-autoload !\n"; exit(1); } else { echo "添加失败!请按任意键继续!"; diff --git a/src/ZM/Framework.php b/src/ZM/Framework.php index 80452334..4f0c8cce 100644 --- a/src/ZM/Framework.php +++ b/src/ZM/Framework.php @@ -45,14 +45,15 @@ class Framework self::$argv = $args; - //定义常量 - include_once "global_defines.php"; - ZMConfig::setDirectory(DataProvider::getWorkingDir() . '/config'); ZMConfig::setEnv($args["env"] ?? ""); if (ZMConfig::get("global") === false) { die ("Global config load failed: " . ZMConfig::$last_error . "\nPlease init first!\n"); } + + //定义常量 + include_once "global_defines.php"; + ZMAtomic::init(); try { $sw = ZMConfig::get("global"); @@ -74,7 +75,6 @@ class Framework die($e->getMessage()); } try { - Console::init( ZMConfig::get("global", "info_level") ?? 2, self::$server, diff --git a/src/ZM/Utils/MessageUtil.php b/src/ZM/Utils/MessageUtil.php index 93a47f1a..22ca5cbc 100644 --- a/src/ZM/Utils/MessageUtil.php +++ b/src/ZM/Utils/MessageUtil.php @@ -5,11 +5,19 @@ namespace ZM\Utils; use ZM\API\CQ; +use ZM\Config\ZMConfig; use ZM\Console\Console; +use ZM\Framework; use ZM\Requests\ZMRequest; class MessageUtil { + /** + * 下载消息中 CQ 码的所有图片,通过 url + * @param $msg + * @param null $path + * @return array|false + */ public static function downloadCQImage($msg, $path = null) { $path = $path ?? DataProvider::getDataFolder() . "images/"; if (!is_dir($path)) mkdir($path); @@ -32,4 +40,41 @@ class MessageUtil } return $files; } + + /** + * 检查消息中是否含有图片 CQ 码 + * @param $msg + * @return bool + */ + public static function containsImage($msg) { + $cq = CQ::getAllCQ($msg, true); + foreach ($cq as $v) { + if ($v->type == "image") { + return true; + } + } + return false; + } + + /** + * 通过本地地址返回图片的 CQ 码 + * type == 0 : 返回图片的 base64 CQ 码 + * type == 1 : 返回图片的 file://路径 CQ 码(路径必须为绝对路径) + * type == 2 : 返回图片的 http://xxx CQ 码(默认为 /images/ 路径就是文件对应所在的目录) + * @param $file + * @param int $type + * @return string + */ + public static function getImageCQFromLocal($file, $type = 0) { + switch ($type) { + case 0: + return CQ::image("base64://" . base64_encode(file_get_contents($file))); + case 1: + return CQ::image("file://" . $file); + case 2: + $info = pathinfo($file); + return CQ::image(ZMConfig::get("global", "http_reverse_link") . "/images/" . $info["basename"]); + } + return ""; + } } \ No newline at end of file diff --git a/src/ZM/Utils/TaskManager.php b/src/ZM/Utils/TaskManager.php index 9bb5974d..2f8e0496 100644 --- a/src/ZM/Utils/TaskManager.php +++ b/src/ZM/Utils/TaskManager.php @@ -4,9 +4,15 @@ namespace ZM\Utils; +use ZM\Console\Console; + class TaskManager { public static function runTask($task_name, $timeout = -1, ...$params) { + if (!isset(server()->setting["task_worker_num"])) { + Console::warning("未开启 TaskWorker 进程,请先修改 global 配置文件启用!"); + return false; + } $r = server()->taskwait(["task" => $task_name, "params" => $params], $timeout); return $r === false ? false : $r["result"]; }