Files
zhamao-framework/src/Framework/FrameworkLoader.php

193 lines
7.8 KiB
PHP
Raw Normal View History

2020-03-02 16:14:20 +08:00
<?php
namespace Framework;
use Co;
use Doctrine\Common\Annotations\AnnotationException;
use Swoole\Http\Request;
use Swoole\Runtime;
use Swoole\WebSocket\Frame;
2020-03-02 16:14:20 +08:00
use ZM\Event\EventHandler;
use Exception;
use Swoole\WebSocket\Server;
use ZM\Http\Response;
/**
* Class FrameworkLoader
* Everything is beginning from here
* @package Framework
*/
class FrameworkLoader
{
/** @var GlobalConfig */
public static $settings;
/** @var FrameworkLoader|null */
public static $instance = null;
/** @var float|string */
public static $run_time;
2020-03-05 14:38:12 +08:00
/**
* @var array
*/
public static $argv;
2020-03-02 16:14:20 +08:00
/** @var Server */
private $server;
2020-05-02 23:27:26 +08:00
public function __construct($args = []) {
2020-03-02 16:14:20 +08:00
if (self::$instance !== null) die("Cannot run two FrameworkLoader in one process!");
self::$instance = $this;
2020-05-23 17:23:29 +08:00
2020-03-02 16:14:20 +08:00
$this->requireGlobalFunctions();
2020-06-05 13:36:30 +08:00
if (LOAD_MODE == 0) define("WORKING_DIR", getcwd());
elseif (LOAD_MODE == 1) define("WORKING_DIR", realpath(__DIR__ . "/../../"));
2020-06-05 13:36:30 +08:00
elseif (LOAD_MODE == 2) echo "Phar mode: " . WORKING_DIR . PHP_EOL;
//$this->registerAutoloader('classLoader');
require_once "DataProvider.php";
if (file_exists(DataProvider::getWorkingDir() . "/vendor/autoload.php")) {
require_once DataProvider::getWorkingDir() . "/vendor/autoload.php";
}
if (LOAD_MODE == 2) {
require_once FRAMEWORK_DIR . "/vendor/autoload.php";
spl_autoload_register('phar_classloader');
}
2020-05-23 17:23:29 +08:00
self::$settings = new GlobalConfig();
if (self::$settings->get("debug_mode") === true) {
$args[] = "--debug-mode";
$args[] = "--disable-console-input";
}
self::$argv = $args;
if (!in_array("--debug-mode", self::$argv)) {
Runtime::enableCoroutine(true, SWOOLE_HOOK_ALL);
}
2020-03-02 16:14:20 +08:00
self::$settings = new GlobalConfig();
ZMBuf::$globals = self::$settings;
if (!self::$settings->success) die("Failed to load global config. Please check config/global.php file");
$this->defineProperties();
//start swoole Framework
$this->selfCheck();
try {
$this->server = new Server(self::$settings->get("host"), self::$settings->get("port"));
$settings = self::$settings->get("swoole");
if (in_array("--daemon", $args)) {
$settings["daemonize"] = 1;
Console::log("已启用守护进程,输出重定向到 " . $settings["log_file"]);
self::$argv[] = "--disable-console-input";
}
$this->server->set($settings);
2020-03-02 16:14:20 +08:00
$this->server->on("WorkerStart", [$this, "onWorkerStart"]);
$this->server->on("message", function ($server, Frame $frame) {
2020-05-06 17:19:59 +08:00
Console::debug("Calling Swoole \"message\" from fd=" . $frame->fd);
EventHandler::callSwooleEvent("message", $server, $frame);
});
2020-03-02 16:14:20 +08:00
$this->server->on("request", function ($request, $response) {
$response = new Response($response);
Console::debug("Receiving Http request event, cid=" . Co::getCid());
2020-03-02 16:14:20 +08:00
EventHandler::callSwooleEvent("request", $request, $response);
});
$this->server->on("open", function ($server, Request $request) {
Console::debug("Calling Swoole \"open\" event from fd=" . $request->fd);
EventHandler::callSwooleEvent("open", $server, $request);
});
$this->server->on("close", function ($server, $fd) {
Console::debug("Calling Swoole \"close\" event from fd=" . $fd);
EventHandler::callSwooleEvent("close", $server, $fd);
});
2020-03-02 16:14:20 +08:00
ZMBuf::initAtomic();
2020-06-05 13:36:30 +08:00
if (in_array("--remote-shell", $args)) RemoteShell::listen($this->server, "127.0.0.1");
if (in_array("--log-error", $args)) ZMBuf::$atomics["info_level"]->set(0);
if (in_array("--log-warning", $args)) ZMBuf::$atomics["info_level"]->set(1);
if (in_array("--log-info", $args)) ZMBuf::$atomics["info_level"]->set(2);
if (in_array("--log-verbose", $args)) ZMBuf::$atomics["info_level"]->set(3);
if (in_array("--log-debug", $args)) ZMBuf::$atomics["info_level"]->set(4);
2020-04-29 15:38:57 +08:00
Console::log(
"host: " . self::$settings->get("host") .
", port: " . self::$settings->get("port") .
", log_level: " . ZMBuf::$atomics["info_level"]->get() .
", version: " . ZM_VERSION .
2020-06-05 13:36:30 +08:00
"\nworking_dir: " . DataProvider::getWorkingDir()
2020-04-29 15:38:57 +08:00
);
global $motd;
2020-05-23 17:23:29 +08:00
if (!file_exists(DataProvider::getWorkingDir() . "/config/motd.txt")) {
echo $motd;
} else {
echo file_get_contents(DataProvider::getWorkingDir() . "/config/motd.txt");
}
if (in_array("--debug-mode", self::$argv))
Console::warning("You are in debug mode, do not use in production!");
2020-03-02 16:14:20 +08:00
$this->server->start();
} catch (Exception $e) {
Console::error("Framework初始化出现错误请检查");
Console::error($e->getMessage());
die;
}
}
2020-05-02 23:27:26 +08:00
private function requireGlobalFunctions() {
require_once __DIR__ . '/global_functions.php';
2020-03-02 16:14:20 +08:00
}
2020-05-02 23:27:26 +08:00
private function registerAutoloader(string $string) {
2020-03-02 16:14:20 +08:00
if (!spl_autoload_register($string)) die("Failed to register autoloader named \"$string\" !");
}
2020-05-02 23:27:26 +08:00
private function defineProperties() {
2020-03-02 16:14:20 +08:00
define("ZM_START_TIME", microtime(true));
define("ZM_DATA", self::$settings->get("zm_data"));
define("ZM_VERSION", json_decode(file_get_contents(__DIR__ . "/../../composer.json"), true)["version"] ?? "unknown");
2020-03-02 16:14:20 +08:00
define("CONFIG_DIR", self::$settings->get("config_dir"));
define("CRASH_DIR", self::$settings->get("crash_dir"));
@mkdir(ZM_DATA);
@mkdir(CONFIG_DIR);
@mkdir(CRASH_DIR);
define("ZM_MATCH_ALL", 0);
define("ZM_MATCH_FIRST", 1);
define("ZM_MATCH_NUMBER", 2);
define("ZM_MATCH_SECOND", 3);
2020-05-23 17:23:29 +08:00
define("ZM_BREAKPOINT", 'if(in_array("--debug-mode", \Framework\FrameworkLoader::$argv)) extract(\Psy\debug(get_defined_vars(), isset($this) ? $this : @get_called_class()));');
2020-03-02 16:14:20 +08:00
}
2020-05-02 23:27:26 +08:00
private function selfCheck() {
2020-03-02 16:14:20 +08:00
if (!extension_loaded("swoole")) die("Can not find swoole extension.\n");
2020-05-23 17:23:29 +08:00
if (version_compare(SWOOLE_VERSION, "4.4.13") == -1) die("You must install swoole version >= 4.4.13 !");
2020-03-02 16:14:20 +08:00
//if (!extension_loaded("gd")) die("Can not find gd extension.\n");
if (!extension_loaded("sockets")) die("Can not find sockets extension.\n");
2020-05-23 17:23:29 +08:00
if (!extension_loaded("ctype")) die("Can not find ctype extension.\n");
2020-03-02 16:14:20 +08:00
if (!function_exists("mb_substr")) die("Can not find mbstring extension.\n");
if (substr(PHP_VERSION, 0, 1) != "7") die("PHP >=7 required.\n");
//if (!function_exists("curl_exec")) die("Can not find curl extension.\n");
//if (!class_exists("ZipArchive")) die("Can not find Zip extension.\n");
//if (!file_exists(CRASH_DIR . "last_error.log")) die("Can not find log file.\n");
return true;
}
/**
* @param \Swoole\Server $server
* @param $worker_id
* @throws AnnotationException
*/
2020-05-02 23:27:26 +08:00
public function onWorkerStart(\Swoole\Server $server, $worker_id) {
2020-03-02 16:14:20 +08:00
self::$instance = $this;
self::$run_time = microtime(true);
EventHandler::callSwooleEvent("WorkerStart", $server, $worker_id);
}
}
2020-04-29 15:38:57 +08:00
global $motd;
$motd = <<<EOL
______
|__ / |__ __ _ _ __ ___ __ _ ___
/ /| '_ \ / _` | '_ ` _ \ / _` |/ _ \
/ /_| | | | (_| | | | | | | (_| | (_) |
/____|_| |_|\__,_|_| |_| |_|\__,_|\___/
2020-05-23 17:23:29 +08:00
2020-04-29 15:38:57 +08:00
EOL;