manager_pid); ProcessManager::createUserProcess('monitor', function () use ($server) { Process::signal(SIGINT, function () { Console::success('用户进程检测到了Ctrl+C'); }); if (Framework::$argv['watch']) { if (extension_loaded('inotify')) { Console::info('Enabled File watcher, framework will reload automatically.'); $fd = inotify_init(); $this->addWatcher(DataProvider::getSourceRootDir() . '/src', $fd); Event::add($fd, function () use ($fd) { $r = inotify_read($fd); Console::verbose('File updated: ' . $r[0]['name']); ZMUtil::reload(); }); Framework::$argv['polling-watch'] = false; // 如果开启了inotify则关闭轮询热更新 } else { Console::warning(zm_internal_errcode('E00024') . '你还没有安装或启用 inotify 扩展,将默认使用轮询检测模式开启热更新!'); Framework::$argv['polling-watch'] = true; } } if (Framework::$argv['polling-watch']) { self::$watch_tick_id = swoole_timer_tick(3000, function () use ($server) { $data = DataProvider::scanDirFiles(DataProvider::getSourceRootDir() . '/src/'); $hash = md5(''); foreach ($data as $file) { $hash = md5($hash . md5_file($file)); } if (self::$last_hash == '') { self::$last_hash = $hash; } elseif (self::$last_hash !== $hash) { self::$last_hash = $hash; $server->reload(); } }); } if (Framework::$argv['interact']) { Console::info('Interact mode'); ZMBuf::$terminal = $r = STDIN; Event::add($r, function () use ($r) { $fget = fgets($r); if ($fget === false) { Event::del($r); return; } $var = trim($fget); if ($var == 'stop') { Event::del($r); } try { Terminal::executeCommand($var); } catch (Exception $e) { Console::error(zm_internal_errcode('E00025') . 'Uncaught exception ' . get_class($e) . ': ' . $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'); } catch (Error $e) { Console::error(zm_internal_errcode('E00025') . 'Uncaught error ' . get_class($e) . ': ' . $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')'); } }); } }); ProcessManager::getUserProcess('monitor')->set(['enable_coroutine' => true]); ProcessManager::getUserProcess('monitor')->start(); /*$dispatcher = new EventDispatcher(OnManagerStartEvent::class); $dispatcher->setRuleFunction(function($v) { return eval("return " . $v->getRule() . ";"); }); $dispatcher->dispatchEvents($server); */ Console::verbose('进程 Manager 已启动'); } private function addWatcher($maindir, $fd) { $dir = scandir($maindir); if ($dir[0] == '.') { unset($dir[0], $dir[1]); } foreach ($dir as $subdir) { if (is_dir($maindir . '/' . $subdir)) { Console::debug('添加监听目录:' . $maindir . '/' . $subdir); inotify_add_watch($fd, $maindir . '/' . $subdir, IN_ATTRIB | IN_ISDIR); $this->addWatcher($maindir . '/' . $subdir, $fd); } } } }