swoole 下开发,修改代码后,自动重启工具

在进行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 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 5

fswatch 这个也可以哈,不过支持~~~~

5年前 评论

嗯嗯,网上搜没现成的PHP的版本的,就干脆利用swoole进程搞了一个,谢谢支持啦,😄

5年前 评论

inotify扩展mac上面不支持,请问有什么好的解决方案吗

4年前 评论

@沐辰 Unix系统,文件监控你可以试一试kqueue

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!