在進行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 協議》,轉載必須註明作者和本文連結