<?php<liu21st@gmail.com>namespace think\swoole;
use Swoole\Http\Server as HttpServer;
use Swoole\Table;
use think\Facade;
use think\Loader;
class Http extends Server
{
protected $app;
protected $appPath;
protected $table;
protected $monitor;
protected $lastMtime;
protected $fieldType = [
'int' => Table::TYPE_INT,
'string' => Table::TYPE_STRING,
'float' => Table::TYPE_FLOAT,
];
protected $fieldSize = [
Table::TYPE_INT => 4,
Table::TYPE_STRING => 32,
Table::TYPE_FLOAT => 8,
];
public function __construct($host, $port, $mode = SWOOLE_PROCESS, $sockType = SWOOLE_SOCK_TCP)
{
$this->swoole = new HttpServer($host, $port, $mode, $sockType);
}
public function setAppPath($path)
{
$this->appPath = $path;
}
public function setMonitor($interval = 2, $path = [])
{
$this->monitor['interval'] = $interval;
$this->monitor['path'] = (array) $path;
}
public function table(array $option)
{
$size = !empty($option['size']) ? $option['size'] : 1024;
$this->table = new Table($size);
foreach ($option['column'] as $field => $type) {
$length = null;
if (is_array($type)) {
list($type, $length) = $type;
}
if (isset($this->fieldType[$type])) {
$type = $this->fieldType[$type];
}
$this->table->column($field, $type, isset($length) ? $length : $this->fieldSize[$type]);
}
$this->table->create();
}
public function option(array $option)
{
if (!empty($option)) {
$this->swoole->set($option);
}
foreach ($this->event as $event) {
if (!empty($option[$event])) {
$this->swoole->on($event, $option[$event]);
} elseif (method_exists($this, 'on' . $event)) {
$this->swoole->on($event, [$this, 'on' . $event]);
}
}
}
public function onWorkerStart($server, $worker_id)
{
$this->app = new Application($this->appPath);
$this->lastMtime = time();
if ($this->table) {
$this->app['swoole_table'] = $this->table;
}
Loader::addClassMap([
'think\\log\\driver\\File' => __DIR__ . '/log/File.php',
]);
Facade::bind([
'think\facade\Cookie' => Cookie::class,
'think\facade\Session' => Session::class,
facade\Application::class => Application::class,
facade\Http::class => Http::class,
]);
$this->app->initialize();
$this->app->bindTo([
'cookie' => Cookie::class,
'session' => Session::class,
]);
if (0 == $worker_id && $this->monitor) {
$this->monitor($server);
}
}
protected function monitor($server)
{
$paths = $this->monitor['path'] ?: [$this->app->getAppPath(), $this->app->getConfigPath()];
$timer = $this->monitor['interval'] ?: 2;
$server->tick($timer, function () use ($paths, $server) {
foreach ($paths as $path) {
$dir = new \RecursiveDirectoryIterator($path);
$iterator = new \RecursiveIteratorIterator($dir);
foreach ($iterator as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) != 'php') {
continue;
}
if ($this->lastMtime < $file->getMTime()) {
$this->lastMtime = $file->getMTime();
echo '[update]' . $file . " reload...\n";
$server->reload();
return;
}
}
}
});
}
public function onRequest($request, $response)
{
$this->app->swoole($request, $response);
}
}