swoole 下开发,修改代码后,自动重启工具
2019-02-12 本文已影响0人
phpdi
在进行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();