initial 2.0.0-a2 commit

This commit is contained in:
jerry
2020-09-29 15:07:43 +08:00
parent 1510e2f0d0
commit f91d24aaaa
59 changed files with 2271 additions and 1475 deletions

View File

@@ -10,13 +10,12 @@ use ZM\Console\Console;
use Swoole\WebSocket\Frame;
use Swoole\WebSocket\Server;
use ZM\Annotation\Swoole\SwooleEventAfter;
use ZM\Annotation\Swoole\SwooleEventAt;
use ZM\Annotation\Swoole\SwooleEvent;
use Exception;
use ZM\Event\EventHandler;
use ZM\Store\ZMBuf;
use ZM\Utils\ZMUtil;
class MessageEvent implements SwooleEvent
class MessageEvent implements SwooleEventInterface
{
/**
* @var Server
@@ -36,7 +35,6 @@ class MessageEvent implements SwooleEvent
* @inheritDoc
*/
public function onActivate() {
ZMUtil::checkWait();
$conn = ManagerGM::get(context()->getFrame()->fd);
try {
if ($conn->getName() == "qq") {
@@ -51,7 +49,7 @@ class MessageEvent implements SwooleEvent
EventHandler::callCQResponse($data);
}
}
foreach (ZMBuf::$events[SwooleEventAt::class] ?? [] as $v) {
foreach (ZMBuf::$events[SwooleEvent::class] ?? [] as $v) {
if (strtolower($v->type) == "message" && $this->parseSwooleRule($v)) {
$c = $v->class;
EventHandler::callWithMiddleware(

View File

@@ -6,17 +6,20 @@ namespace ZM\Event\Swoole;
use Closure;
use Exception;
use ZM\Config\ZMConfig;
use ZM\Console\Console;
use Framework\ZMBuf;
use ZM\Event\EventManager;
use ZM\Store\ZMBuf;
use Swoole\Http\Request;
use ZM\Annotation\Swoole\SwooleEventAfter;
use ZM\Annotation\Swoole\SwooleEventAt;
use ZM\Annotation\Swoole\SwooleEvent;
use ZM\Event\EventHandler;
use ZM\Http\Response;
use ZM\Utils\DataProvider;
use ZM\Utils\HttpUtil;
use ZM\Utils\ZMUtil;
class RequestEvent implements SwooleEvent
class RequestEvent implements SwooleEventInterface
{
/**
* @var Request
@@ -37,15 +40,14 @@ class RequestEvent implements SwooleEvent
* @throws Exception
*/
public function onActivate() {
ZMUtil::checkWait();
foreach (\ZM\Config\ZMConfig::get("global", "http_header") as $k => $v) {
foreach (ZMConfig::get("global", "http_header") as $k => $v) {
$this->response->setHeader($k, $v);
}
$uri = $this->request->server["request_uri"];
Console::verbose($this->request->server["remote_addr"] . " request " . $uri);
$uri = explode("/", $uri);
$uri = array_diff($uri, ["..", "", "."]);
$node = ZMBuf::$req_mapping;
$node = EventManager::$req_mapping;
$params = [];
while (true) {
$r = array_shift($uri);
@@ -81,9 +83,9 @@ class RequestEvent implements SwooleEvent
}
}
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"];
if (ZMConfig::get("global", "static_file_server")["status"]) {
$base_dir = ZMConfig::get("global", "static_file_server")["document_root"];
$base_index = ZMConfig::get("global", "static_file_server")["document_index"];
$uri = $this->request->server["request_uri"];
$path = realpath($base_dir . urldecode($uri));
if ($path !== false) {
@@ -98,7 +100,7 @@ class RequestEvent implements SwooleEvent
if (is_file($path . $vp)) {
Console::info("[200] " . $uri . " (static)");
$exp = strtolower(pathinfo($path . $vp)['extension'] ?? "unknown");
$this->response->setHeader("Content-Type", ZMBuf::config("file_header")[$exp] ?? "application/octet-stream");
$this->response->setHeader("Content-Type", ZMConfig::get("file_header")[$exp] ?? "application/octet-stream");
$this->response->end(file_get_contents($path . $vp));
return $this;
}
@@ -106,14 +108,14 @@ class RequestEvent implements SwooleEvent
} elseif (is_file($path)) {
Console::info("[200] " . $uri . " (static)");
$exp = strtolower(pathinfo($path)['extension'] ?? "unknown");
$this->response->setHeader("Content-Type", ZMBuf::config("file_header")[$exp] ?? "application/octet-stream");
$this->response->setHeader("Content-Type", ZMConfig::get("file_header")[$exp] ?? "application/octet-stream");
$this->response->end(file_get_contents($path));
return $this;
}
}
}
$this->response->status(404);
$this->response->end(ZMUtil::getHttpCodePage(404));
$this->response->end(HttpUtil::getHttpCodePage(404));
return $this;
}
context()->setCache("params", $params);
@@ -131,7 +133,7 @@ class RequestEvent implements SwooleEvent
}
);
}
foreach (ZMBuf::$events[SwooleEventAt::class] ?? [] as $v) {
foreach (ZMBuf::$events[SwooleEvent::class] ?? [] as $v) {
if (strtolower($v->type) == "request" && $this->parseSwooleRule($v)) {
$c = $v->class;
EventHandler::callWithMiddleware($c, $v->method, ["request" => $this->request, "response" => $this->response], []);
@@ -141,7 +143,7 @@ class RequestEvent implements SwooleEvent
if (!$this->response->isEnd()) {
$this->response->status(404);
$this->response->end(ZMUtil::getHttpCodePage(404));
$this->response->end(HttpUtil::getHttpCodePage(404));
}
return $this;
}

View File

@@ -6,15 +6,15 @@ namespace ZM\Event\Swoole;
use ZM\Event\Event;
interface SwooleEvent extends Event
interface SwooleEventInterface extends Event
{
/**
* @return SwooleEvent
* @return SwooleEventInterface
*/
public function onActivate();
/**
* @return SwooleEvent
* @return SwooleEventInterface
*/
public function onAfter();
}
}

View File

@@ -10,12 +10,12 @@ use ZM\ConnectionManager\ManagerGM;
use ZM\Console\Console;
use Swoole\Server;
use ZM\Annotation\Swoole\SwooleEventAfter;
use ZM\Annotation\Swoole\SwooleEventAt;
use ZM\Annotation\Swoole\SwooleEvent;
use ZM\Event\EventHandler;
use ZM\Store\ZMBuf;
use ZM\Utils\ZMUtil;
class WSCloseEvent implements SwooleEvent
class WSCloseEvent implements SwooleEventInterface
{
public $server;
@@ -31,10 +31,9 @@ class WSCloseEvent implements SwooleEvent
* @throws AnnotationException
*/
public function onActivate() {
Console::info("Closed #{$this->fd}");
ZMUtil::checkWait();
Console::debug("Websocket closed #{$this->fd}");
set_coroutine_params(["server" => $this->server, "fd" => $this->fd, "connection" => ManagerGM::get($this->fd)]);
foreach(ZMBuf::$events[SwooleEventAt::class] ?? [] as $v) {
foreach(ZMBuf::$events[SwooleEvent::class] ?? [] as $v) {
if(strtolower($v->type) == "close" && $this->parseSwooleRule($v)) {
$c = $v->class;
EventHandler::callWithMiddleware($c, $v->method, ["server" => $this->server, "fd" => $this->fd], []);

View File

@@ -13,12 +13,11 @@ use ZM\Console\Console;
use Swoole\Http\Request;
use Swoole\WebSocket\Server;
use ZM\Annotation\Swoole\SwooleEventAfter;
use ZM\Annotation\Swoole\SwooleEventAt;
use ZM\Annotation\Swoole\SwooleEvent;
use ZM\Event\EventHandler;
use ZM\Store\ZMBuf;
use ZM\Utils\ZMUtil;
class WSOpenEvent implements SwooleEvent
class WSOpenEvent implements SwooleEventInterface
{
/**
* @var Server
@@ -41,10 +40,9 @@ class WSOpenEvent implements SwooleEvent
* @throws AnnotationException
*/
public function onActivate() {
ZMUtil::checkWait();
ManagerGM::pushConnect($this->request->fd);
$type = strtolower($this->request->get["type"] ?? $this->request->header["x-client-role"] ?? "");
$type_conn = $this->getTypeClassName($type);
ManagerGM::pushConnect($this->request->fd, $type_conn);
if ($type_conn == "qq") {
ManagerGM::setName($this->request->fd, "qq");
$qq = $this->request->get["qq"] ?? $this->request->header["x-self-id"] ?? "";
@@ -65,7 +63,7 @@ class WSOpenEvent implements SwooleEvent
$this->conn = ManagerGM::get($this->request->fd);
}
set_coroutine_params(["server" => $this->server, "request" => $this->request, "connection" => $this->conn]);
foreach (ZMBuf::$events[SwooleEventAt::class] ?? [] as $v) {
foreach (ZMBuf::$events[SwooleEvent::class] ?? [] as $v) {
if (strtolower($v->type) == "open" && $this->parseSwooleRule($v) === true) {
$c = $v->class;
EventHandler::callWithMiddleware(
@@ -104,14 +102,5 @@ 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

@@ -1,189 +0,0 @@
<?php
namespace ZM\Event\Swoole;
use Doctrine\Common\Annotations\AnnotationException;
use Exception;
use PDO;
use ReflectionException;
use Swoole\Coroutine;
use Swoole\Database\PDOConfig;
use Swoole\Database\PDOPool;
use Swoole\Process;
use Swoole\Timer;
use ZM\Annotation\AnnotationParser;
use ZM\Annotation\Swoole\OnStart;
use ZM\Config\ZMConfig;
use ZM\Context\ContextInterface;
use ZM\DB\DB;
use ZM\Console\Console;
use Swoole\Server;
use ZM\Event\EventHandler;
use ZM\Exception\DbException;
use ZM\Store\ZMBuf;
use ZM\Utils\DataProvider;
use ZM\Utils\Terminal;
use ZM\Utils\ZMUtil;
class WorkerStartEvent implements SwooleEvent
{
private $worker_id;
/**
* @var Server
*/
private $server;
public function __construct(Server $server, $worker_id) {
$this->server = $server;
$this->worker_id = $worker_id;
}
/**
* @return WorkerStartEvent
* @throws AnnotationException
* @throws ReflectionException
* @throws DbException
*/
public function onActivate(): WorkerStartEvent {
Console::info("Worker #{$this->server->worker_id} 启动中");
ZMBuf::$server = $this->server;
ZMBuf::resetCache(); //清空变量缓存
ZMBuf::set("wait_start", []); //添加队列在workerStart运行完成前先让其他协程等待执行
$this->resetConnections();//释放所有与framework的连接
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 (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) {
$v = trim($v);
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 = ZMConfig::get("global", "sql_config");
ZMBuf::$sql_pool = new PDOPool((new PDOConfig())
->withHost($sql["sql_host"])
->withPort($sql["sql_port"])
// ->withUnixSocket('/tmp/mysql.sock')
->withDbName($sql["sql_database"])
->withCharset('utf8mb4')
->withUsername($sql["sql_username"])
->withPassword($sql["sql_password"])
->withOptions($sql["sql_options"] ?? [PDO::ATTR_STRINGIFY_FETCHES => false])
);
DB::initTableList();
}
$this->loadAllClass(); //加载composer资源、phar外置包、注解解析注册等
return $this;
}
/**
* @return WorkerStartEvent
* @throws AnnotationException
*/
public function onAfter(): WorkerStartEvent {
foreach (ZMBuf::get("wait_start") as $v) {
Coroutine::resume($v);
}
ZMBuf::unsetCache("wait_start");
set_coroutine_params(["server" => $this->server, "worker_id" => $this->worker_id]);
if($this->server->worker_id === 0) {
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], []);
}
Console::debug("@OnStart 执行完毕");
}
return $this;
}
private function resetConnections() {
foreach ($this->server->connections as $v) {
$this->server->close($v);
}
if (ZMBuf::$sql_pool !== null) {
ZMBuf::$sql_pool->close();
ZMBuf::$sql_pool = null;
}
}
/**
* @throws ReflectionException
* @throws Exception
*/
private function loadAllClass() {
//加载phar包
Console::info("加载外部phar包中");
$dir = DataProvider::getWorkingDir() . "/resources/package/";
if (version_compare(SWOOLE_VERSION, "4.4.0", ">=")) Timer::clearAll();
if (is_dir($dir)) {
$list = scandir($dir);
unset($list[0], $list[1]);
foreach ($list as $v) {
if (is_dir($dir . $v)) continue;
if (pathinfo($dir . $v, 4) == "phar") {
Console::verbose("加载Phar: " . $dir . $v . "");
require_once($dir . $v);
}
}
}
//加载composer类
//remove stupid duplicate code
//加载各个模块的注解类,以及反射
Console::info("检索Module中");
$parser = new AnnotationParser();
$parser->addRegisterPath(DataProvider::getWorkingDir() . "/src/Module/", "Module");
$parser->registerMods();
$parser->sortLevels();
//加载自定义的全局函数
Console::debug("加载自定义的全局函数中");
$this->afterCheck();
}
private function setAutosaveTimer($globals) {
DataProvider::$buffer_list = [];
zm_timer_tick($globals * 1000, function () {
DataProvider::saveBuffer();
});
}
/**
* @throws Exception
*/
private function afterCheck() {
$context_class = ZMConfig::get("global", "context_class");
if (!is_a($context_class, ContextInterface::class, true)) {
throw new Exception("Context class must implemented from ContextInterface!");
}
}
}