swoole 下開發,修改程式碼後,自動重啟工具

phpdi發表於2018-11-08

在進行swoole開發的時候,每次修改了指令碼就需要手動重啟服務,修改才能生效,針對這個場景,編寫這個指令碼,實現修改了指令碼讓伺服器自動進行重啟.
github地址

<?php
/**
 * 此類用於實現監聽專案檔案改變後自動重啟swoole-server
 * 依賴: php inotify擴充套件
 * Class SwooleCli
 */
class SwooleCli
{
    //監聽的事件
    const WATCH_CHANGED=IN_MODIFY | IN_CLOSE_WRITE | IN_MOVE | IN_CREATE | IN_DELETE;
    //不需要監測的資料夾
    const SKIP_DIR=['/vendor','/bootstrap','/storage','/tests','/swoolecli'];
    //重啟間隔,防止頻繁重啟
    const RESTART_INTERVAL=1000;//毫秒
    //重啟伺服器的命令
    const RESTART_COMMAND=[
        '/usr/bin/php',
        __DIR__.'/artisan',
        'websocket:start'
    ];
    private $fd;//inotify控制程式碼
    private $rootDir;//專案根目錄
    private $skipDir;//不需要監聽的目錄
    private $dirNum=0;//記錄目錄條數
    private $swooleServerPid;//swoole伺服器的程式id,用於重啟殺死子類程式
    private $lastStartTime;//上次重啟時間
    public function __construct()
    {
        $this->fd=inotify_init();
        $this->rootDir=str_replace('/swoolecli','',__DIR__);
        //設定不需要監聽的目錄
        $this->setSkipDir();
        //開始掃描目錄
        $this->scanDirRecursion($this->rootDir);
        //監聽單個目錄
        //$this->setWatch($this->rootDir);
        swoole_process::signal(SIGCHLD, function($sig) {
            //必須為false,非阻塞模式
            while($ret =  swoole_process::wait(false)) {
                echo '程式[pid='.$ret['pid'].']已被回收'.PHP_EOL;
            }
        });
    }
    public function __get($name)
    {
     return isset($this->$name)?$this->$name:null;
    }
    /**
    * 設定需要不需要監聽的目錄
    */
    private function setSkipDir()
    {
        $this->skipDir=array_map(function($v){
            return $this->rootDir.$v;
        },self::SKIP_DIR);
    }
    /**
    * 遞迴掃描目錄,並加上監聽
    */
    private function scanDirRecursion($dir)
    {
        if(!is_dir($dir) || in_array($dir,$this->skipDir)) return;
        //是目錄加監聽
        $this->setWatch($dir);
        $dirArr=scandir($dir);
        if(!is_array($dirArr))return;
        foreach ($dirArr as $v){
            if($v=='.' || $v=='..') continue;
            $newPath=$dir.'/'.$v;
            if(!is_dir($newPath)) continue;
            $this->dirNum++;
            //遞迴呼叫自己
            $this->scanDirRecursion($newPath);
        }
    }
    /**
    * 設定監聽
    */
    public function setWatch($dir)
    {
        //監聽檔案
        inotify_add_watch($this->fd, $dir, self::WATCH_CHANGED);
        if($this->dirNum==1){
            //加入到swoole的事件迴圈中
            swoole_event_add($this->fd, function ($fd) {
                $events = inotify_read($fd);
                if ($events) {
                    $mic=$this->microtime();
                    //防止頻繁重啟
                    if($mic-$this->lastStartTime>self::RESTART_INTERVAL){
                        $this->restart();
                        $this->lastStartTime=$mic;
                    }
                }
            });
            $this->restart();
        }
    }
    /**
    * 重啟swoole指令碼
    */
    public function restart()
    {
        $this->swooleServerPid && swoole_process::kill($this->swooleServerPid);
        echo '伺服器重啟中...'.PHP_EOL;
        //開一個程式來進行重啟
        $process = new swoole_process(function(swoole_process $worker){
            $worker->exec(self::RESTART_COMMAND[0],[self::RESTART_COMMAND[1],self::RESTART_COMMAND[2]]);
        }, false, false);
        $this->swooleServerPid=$process->start();
        echo '重啟成功,pid:'.$this->swooleServerPid.PHP_EOL;
    }
    public function microtime()
    {
        $mic=microtime(true);
        $mic=substr($mic,2);
        return $mic*1000;
    }
}
 $swooleCli=new SwooleCli();
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章