initial 2.0 commit

This commit is contained in:
jerry
2020-08-31 10:11:06 +08:00
parent b6756179f5
commit beb1f5f063
69 changed files with 1237 additions and 2090 deletions

View File

@@ -5,17 +5,15 @@ namespace ZM\Event\Swoole;
use Closure;
use Framework\Console;
use Framework\ZMBuf;
use ZM\ConnectionManager\ManagerGM;
use ZM\Console\Console;
use Swoole\WebSocket\Frame;
use Swoole\WebSocket\Server;
use ZM\Annotation\Swoole\SwooleEventAfter;
use ZM\Annotation\Swoole\SwooleEventAt;
use ZM\Connection\ConnectionManager;
use Exception;
use ZM\Event\EventHandler;
use ZM\ModBase;
use ZM\ModHandleType;
use ZM\Store\ZMBuf;
use ZM\Utils\ZMUtil;
class MessageEvent implements SwooleEvent
@@ -39,15 +37,15 @@ class MessageEvent implements SwooleEvent
*/
public function onActivate() {
ZMUtil::checkWait();
$conn = ConnectionManager::get(context()->getFrame()->fd);
$conn = ManagerGM::get(context()->getFrame()->fd);
try {
if ($conn->getType() == "qq") {
if ($conn->getName() == "qq") {
$data = json_decode(context()->getFrame()->data, true);
if (isset($data["post_type"])) {
set_coroutine_params(["data" => $data, "connection" => $conn]);
ctx()->setCache("level", 0);
Console::debug("Calling CQ Event from fd=" . $conn->fd);
EventHandler::callCQEvent($data, ConnectionManager::get(context()->getFrame()->fd), 0);
Console::debug("Calling CQ Event from fd=" . $conn->getFd());
EventHandler::callCQEvent($data, ManagerGM::get(context()->getFrame()->fd), 0);
} else{
set_coroutine_params(["connection" => $conn]);
EventHandler::callCQResponse($data);
@@ -78,10 +76,8 @@ class MessageEvent implements SwooleEvent
public function onAfter() {
foreach (ZMBuf::$events[SwooleEventAfter::class] ?? [] as $v) {
if (strtolower($v->type) == "message" && $this->parseSwooleRule($v) === true) {
$conn = ConnectionManager::get($this->frame->fd);
$c = $v->class;
/** @var ModBase $class */
$class = new $c(["server" => $this->server, "frame" => $this->frame, "connection" => $conn], ModHandleType::SWOOLE_MESSAGE);
$class = new $c();
call_user_func_array([$class, $v->method], []);
if (context()->getCache("block_continue") === true) break;
}
@@ -92,7 +88,7 @@ class MessageEvent implements SwooleEvent
private function parseSwooleRule($v) {
switch (explode(":", $v->rule)[0]) {
case "connectType": //websocket连接类型
if ($v->callback instanceof Closure) return call_user_func($v->callback, ConnectionManager::get($this->frame->fd));
if ($v->callback instanceof Closure) return call_user_func($v->callback, ManagerGM::get($this->frame->fd));
break;
case "dataEqual": //handle websocket message事件时才能用
if ($v->callback instanceof Closure) return call_user_func($v->callback, $this->frame->data);

View File

@@ -6,14 +6,14 @@ namespace ZM\Event\Swoole;
use Closure;
use Exception;
use Framework\Console;
use ZM\Console\Console;
use Framework\ZMBuf;
use Swoole\Http\Request;
use ZM\Annotation\Swoole\SwooleEventAfter;
use ZM\Annotation\Swoole\SwooleEventAt;
use ZM\Event\EventHandler;
use ZM\Http\Response;
use Framework\DataProvider;
use ZM\Utils\DataProvider;
use ZM\Utils\ZMUtil;
class RequestEvent implements SwooleEvent
@@ -38,7 +38,7 @@ class RequestEvent implements SwooleEvent
*/
public function onActivate() {
ZMUtil::checkWait();
foreach (ZMBuf::globals("http_header") as $k => $v) {
foreach (\ZM\Config\ZMConfig::get("global", "http_header") as $k => $v) {
$this->response->setHeader($k, $v);
}
$uri = $this->request->server["request_uri"];
@@ -81,9 +81,9 @@ class RequestEvent implements SwooleEvent
}
}
if (ZMBuf::globals("static_file_server")["status"]) {
$base_dir = ZMBuf::globals("static_file_server")["document_root"];
$base_index = ZMBuf::globals("static_file_server")["document_index"];
if (\ZM\Config\ZMConfig::get("global", "static_file_server")["status"]) {
$base_dir = \ZM\Config\ZMConfig::get("global", "static_file_server")["document_root"];
$base_index = \ZM\Config\ZMConfig::get("global", "static_file_server")["document_index"];
$uri = $this->request->server["request_uri"];
$path = realpath($base_dir . urldecode($uri));
if ($path !== false) {
@@ -116,7 +116,6 @@ class RequestEvent implements SwooleEvent
$this->response->end(ZMUtil::getHttpCodePage(404));
return $this;
}
context()->setCache("params", $params);
if (in_array(strtoupper($this->request->server["request_method"]), $node["request_method"] ?? [])) { //判断目标方法在不在里面

View File

@@ -6,12 +6,13 @@ namespace ZM\Event\Swoole;
use Closure;
use Doctrine\Common\Annotations\AnnotationException;
use Framework\ZMBuf;
use ZM\ConnectionManager\ManagerGM;
use ZM\Console\Console;
use Swoole\Server;
use ZM\Annotation\Swoole\SwooleEventAfter;
use ZM\Annotation\Swoole\SwooleEventAt;
use ZM\Connection\ConnectionManager;
use ZM\Event\EventHandler;
use ZM\Store\ZMBuf;
use ZM\Utils\ZMUtil;
class WSCloseEvent implements SwooleEvent
@@ -30,8 +31,9 @@ class WSCloseEvent implements SwooleEvent
* @throws AnnotationException
*/
public function onActivate() {
Console::info("Closed #{$this->fd}");
ZMUtil::checkWait();
set_coroutine_params(["server" => $this->server, "fd" => $this->fd, "connection" => ConnectionManager::get($this->fd)]);
set_coroutine_params(["server" => $this->server, "fd" => $this->fd, "connection" => ManagerGM::get($this->fd)]);
foreach(ZMBuf::$events[SwooleEventAt::class] ?? [] as $v) {
if(strtolower($v->type) == "close" && $this->parseSwooleRule($v)) {
$c = $v->class;
@@ -39,7 +41,7 @@ class WSCloseEvent implements SwooleEvent
if(context()->getCache("block_continue") === true) break;
}
}
ConnectionManager::close($this->fd);
ManagerGM::popConnect($this->fd);
return $this;
}
@@ -61,7 +63,7 @@ class WSCloseEvent implements SwooleEvent
private function parseSwooleRule($v) {
switch (explode(":", $v->rule)[0]) {
case "connectType": //websocket连接类型
if ($v->callback instanceof Closure) return call_user_func($v->callback, ConnectionManager::get($this->fd));
if ($v->callback instanceof Closure) return call_user_func($v->callback, ManagerGM::get($this->fd));
break;
}
return true;

View File

@@ -6,19 +6,16 @@ namespace ZM\Event\Swoole;
use Closure;
use Doctrine\Common\Annotations\AnnotationException;
use Framework\Console;
use Framework\ZMBuf;
use ZM\Config\ZMConfig;
use ZM\ConnectionManager\ConnectionObject;
use ZM\ConnectionManager\ManagerGM;
use ZM\Console\Console;
use Swoole\Http\Request;
use Swoole\WebSocket\Server;
use ZM\Annotation\Swoole\SwooleEventAfter;
use ZM\Annotation\Swoole\SwooleEventAt;
use ZM\Connection\ConnectionManager;
use ZM\Connection\CQConnection;
use ZM\Connection\UnknownConnection;
use ZM\Connection\WSConnection;
use ZM\Event\EventHandler;
use ZM\ModBase;
use ZM\ModHandleType;
use ZM\Store\ZMBuf;
use ZM\Utils\ZMUtil;
class WSOpenEvent implements SwooleEvent
@@ -31,9 +28,7 @@ class WSOpenEvent implements SwooleEvent
* @var Request
*/
private $request;
/**
* @var WSConnection
*/
/** @var ConnectionObject */
private $conn;
public function __construct(Server $server, Request $request) {
@@ -47,25 +42,28 @@ class WSOpenEvent implements SwooleEvent
*/
public function onActivate() {
ZMUtil::checkWait();
ManagerGM::pushConnect($this->request->fd);
$type = strtolower($this->request->get["type"] ?? $this->request->header["x-client-role"] ?? "");
$type_conn = ConnectionManager::getTypeClassName($type);
if ($type_conn == CQConnection::class) {
$type_conn = $this->getTypeClassName($type);
if ($type_conn == "qq") {
ManagerGM::setName($this->request->fd, "qq");
$qq = $this->request->get["qq"] ?? $this->request->header["x-self-id"] ?? "";
$self_token = ZMBuf::globals("access_token") ?? "";
if(isset($this->request->header["authorization"])) {
$self_token = ZMConfig::get("global", "access_token") ?? "";
if (isset($this->request->header["authorization"])) {
Console::debug($this->request->header["authorization"]);
}
$remote_token = $this->request->get["token"] ?? (isset($this->request->header["authorization"]) ? explode(" ", $this->request->header["authorization"])[1] : "");
if ($qq != "" && ($self_token == $remote_token)) $this->conn = new CQConnection($this->server, $this->request->fd, $qq);
else {
$this->conn = new UnknownConnection($this->server, $this->request->fd);
if ($qq != "" && ($self_token == $remote_token)) {
ManagerGM::setOption($this->request->fd, "connect_id", $qq);
$this->conn = ManagerGM::get($this->request->fd);
} else {
$this->conn = ManagerGM::get($this->request->fd);
Console::warning("connection of CQ has invalid QQ or token!");
Console::debug("Remote token: ".$remote_token);
Console::debug("Remote token: " . $remote_token);
}
} else {
$this->conn = new $type_conn($this->server, $this->request->fd);
$this->conn = ManagerGM::get($this->request->fd);
}
ZMBuf::$connect[$this->request->fd] = $this->conn;
set_coroutine_params(["server" => $this->server, "request" => $this->request, "connection" => $this->conn]);
foreach (ZMBuf::$events[SwooleEventAt::class] ?? [] as $v) {
if (strtolower($v->type) == "open" && $this->parseSwooleRule($v) === true) {
@@ -86,11 +84,10 @@ class WSOpenEvent implements SwooleEvent
* @inheritDoc
*/
public function onAfter() {
if (!$this->conn->exists()) return $this;
if (!$this->server->exists($this->conn->getFd())) return $this;
foreach (ZMBuf::$events[SwooleEventAfter::class] ?? [] as $v) {
if (strtolower($v->type) == "open" && $this->parseSwooleRule($v) === true) {
/** @var ModBase $class */
$class = new $v["class"](["server" => $this->server, "request" => $this->request, "connection" => $this->conn], ModHandleType::SWOOLE_OPEN);
$class = new $v["class"]();
call_user_func_array([$class, $v["method"]], [$this->conn]);
if (context()->getCache("block_continue") === true) break;
}
@@ -106,4 +103,15 @@ class WSOpenEvent implements SwooleEvent
}
return true;
}
private function getTypeClassName(string $type) {
$map = [
"qq" => "qq",
"universal" => "qq",
"webconsole" => "webconsole",
"proxy" => "proxy",
"terminal" => "terminal"
];
return $map[$type] ?? "default";
}
}

View File

@@ -4,7 +4,6 @@
namespace ZM\Event\Swoole;
use Co;
use Doctrine\Common\Annotations\AnnotationException;
use Exception;
use PDO;
@@ -14,20 +13,18 @@ use Swoole\Database\PDOConfig;
use Swoole\Database\PDOPool;
use Swoole\Process;
use Swoole\Timer;
use ZM\Annotation\AnnotationBase;
use ZM\Annotation\AnnotationParser;
use ZM\Annotation\Swoole\OnStart;
use ZM\Annotation\Swoole\SwooleEventAfter;
use ZM\Connection\ConnectionManager;
use ZM\Config\ZMConfig;
use ZM\Context\ContextInterface;
use ZM\DB\DB;
use Framework\Console;
use Framework\GlobalConfig;
use Framework\ZMBuf;
use ZM\Console\Console;
use Swoole\Server;
use ZM\Event\EventHandler;
use ZM\Exception\DbException;
use Framework\DataProvider;
use ZM\Store\ZMBuf;
use ZM\Utils\DataProvider;
use ZM\Utils\Terminal;
use ZM\Utils\ZMUtil;
class WorkerStartEvent implements SwooleEvent
@@ -50,50 +47,46 @@ class WorkerStartEvent implements SwooleEvent
* @throws DbException
*/
public function onActivate(): WorkerStartEvent {
Console::info("Worker启动中");
ZMBuf::$server = $this->server;
Console::listenConsole(); //这个方法只能在这里调用且如果worker_num不为1的话此功能不可用
Process::signal(SIGINT, function () {
Console::warning("Server interrupted by keyboard.");
ZMUtil::stop(true);
});
Console::info("Worker #{$this->server->worker_id} 启动中");
ZMBuf::$server = $this->server;
ZMBuf::resetCache(); //清空变量缓存
ZMBuf::set("wait_start", []); //添加队列在workerStart运行完成前先让其他协程等待执行
$this->resetConnections();//释放所有与framework的连接
//设置炸毛buf中储存的对象
ZMBuf::$globals = new GlobalConfig();
ZMBuf::$config = [];
$file = scandir(DataProvider::getWorkingDir() . '/config/');
unset($file[0], $file[1]);
foreach ($file as $k => $v) {
if ($v == "global.php") continue;
$name = explode(".", $v);
if (($prefix = end($name)) == "json") {
ZMBuf::$config[$name[0]] = json_decode(Co::readFile(DataProvider::getWorkingDir() . '/config/' . $v), true);
Console::info("已读取配置文件:" . $v);
} elseif ($prefix == "php") {
ZMBuf::$config[$name[0]] = include_once DataProvider::getWorkingDir() . '/config/' . $v;
if (is_array(ZMBuf::$config[$name[0]]))
Console::info("已读取配置文件:" . $v);
}
global $terminal_id;
Terminal::listenConsole($terminal_id); //这个方法只能在这里调用且如果worker_num不为1的话此功能不可用
// 这里执行的是只需要执行一遍的代码,比如终端监听器和键盘监听器
if ($this->server->worker_id === 0) {
if($terminal_id !== null) Console::info("监听console输入");
Process::signal(SIGINT, function () {
echo PHP_EOL;
Console::warning("Server interrupted by keyboard.");
ZMUtil::stop();
});
ZMBuf::$atomics['reload_time']->add(1);
$this->setAutosaveTimer(ZMConfig::get("global", "auto_save_interval"));
} else {
Process::signal(SIGINT, function () {
// Do Nothing
});
}
if (ZMBuf::globals("sql_config")["sql_host"] != "") {
if (ZMConfig::get("global", "sql_config")["sql_host"] != "") {
Console::info("新建SQL连接池中");
ob_start();
phpinfo();
$str = ob_get_clean();
$str = explode("\n", $str);
foreach($str as $k => $v) {
foreach ($str as $k => $v) {
$v = trim($v);
if($v == "") continue;
if(mb_strpos($v, "API Extensions") === false) continue;
if(mb_strpos($v, "pdo_mysql") === false) {
if ($v == "") continue;
if (mb_strpos($v, "API Extensions") === false) continue;
if (mb_strpos($v, "pdo_mysql") === false) {
throw new DbException("未安装 mysqlnd php-mysql扩展。");
}
}
$sql = ZMBuf::globals("sql_config");
$sql = ZMConfig::get("global", "sql_config");
ZMBuf::$sql_pool = new PDOPool((new PDOConfig())
->withHost($sql["sql_host"])
->withPort($sql["sql_port"])
@@ -107,11 +100,6 @@ class WorkerStartEvent implements SwooleEvent
DB::initTableList();
}
ZMBuf::$atomics['reload_time']->add(1);
Console::info("监听console输入");
$this->setAutosaveTimer(ZMBuf::globals("auto_save_interval"));
$this->loadAllClass(); //加载composer资源、phar外置包、注解解析注册等
return $this;
}
@@ -126,22 +114,14 @@ class WorkerStartEvent implements SwooleEvent
}
ZMBuf::unsetCache("wait_start");
set_coroutine_params(["server" => $this->server, "worker_id" => $this->worker_id]);
foreach (ZMBuf::$events[OnStart::class] ?? [] as $v) {
$class_name = $v->class;
Console::debug("正在调用启动时函数: " . $class_name . " -> " . $v->method);
EventHandler::callWithMiddleware($class_name, $v->method, ["server" => $this->server, "worker_id" => $this->worker_id], []);
}
foreach (ZMBuf::$events[SwooleEventAfter::class] ?? [] as $v) {
/** @var AnnotationBase $v */
if (strtolower($v->type) == "workerstart") {
if($this->server->worker_id === 0) {
foreach (ZMBuf::$events[OnStart::class] ?? [] as $v) {
$class_name = $v->class;
Console::debug("正在调用启动时函数after: " . $class_name . " -> " . $v->method);
Console::debug("正在调用启动时函数: " . $class_name . " -> " . $v->method);
EventHandler::callWithMiddleware($class_name, $v->method, ["server" => $this->server, "worker_id" => $this->worker_id], []);
if (context()->getCache("block_continue") === true) break;
}
Console::debug("@OnStart 执行完毕");
}
Console::debug("调用完毕!");
return $this;
}
@@ -156,7 +136,6 @@ class WorkerStartEvent implements SwooleEvent
}
/**
* @throws AnnotationException
* @throws ReflectionException
* @throws Exception
*/
@@ -181,15 +160,13 @@ class WorkerStartEvent implements SwooleEvent
//加载各个模块的注解类,以及反射
Console::info("检索Module中");
AnnotationParser::registerMods();
//加载Custom目录下的自定义的内部类
ConnectionManager::registerCustomClass();
$parser = new AnnotationParser();
$parser->addRegisterPath(DataProvider::getWorkingDir() . "/src/Module/", "Module");
$parser->registerMods();
$parser->sortLevels();
//加载自定义的全局函数
Console::debug("加载自定义的全局函数中");
if (file_exists(DataProvider::getWorkingDir() . "/src/Custom/global_function.php"))
require_once DataProvider::getWorkingDir() . "/src/Custom/global_function.php";
$this->afterCheck();
}
@@ -204,7 +181,7 @@ class WorkerStartEvent implements SwooleEvent
* @throws Exception
*/
private function afterCheck() {
$context_class = ZMBuf::globals("context_class");
$context_class = ZMConfig::get("global", "context_class");
if (!is_a($context_class, ContextInterface::class, true)) {
throw new Exception("Context class must implemented from ContextInterface!");
}