/** * socket事件回调函数 * @param [resource] $socket [服务器套接字] * @param [int] $ev_tag [事件标志] * @param [array] $args [回调参数] * @return [none] */ public function handle($socket = null, $ev_tag = null, $args = null) { // 回去远程命令 date_default_timezone_set('Asia/Shanghai'); if (null === $socket) { $cmds = new \stdClass(); $cmds->command = '_finished_'; } else { $rec_socket = stream_socket_accept($socket); $cmds = $this->_parseCmd($rec_socket); } if (empty($cmds)) { $cmds = array(); } $cmds = is_object($cmds) ? array($cmds) : $cmds; $log_file = Flight::conf()->get('cli.sys.rpc_logpath') . date('Y-m-d') . '.log'; // 逐个处理命令 foreach ($cmds as $cmd) { if (!isset($cmd->params)) { $cmd->params = array(); } $cur_cmd = $cmd; if ($cur_cmd->command == '_status_') { // 进程结束通知 $status = array(); $status['start_time'] = date('Y-m-d H:i:s', Process::$status['start_time']); $status['runing_list'] = $this->_runing_list; // $wait_cmd = array(); // array_walk($this->_cmd_queue, function($v, $k)use(&$wait_cmd){ // $wait_cmd[] = $v['command']; // }); $status['waiting_list'] = $this->_cmd_queue; fwrite($rec_socket, json_encode($status)); continue; } elseif ($cur_cmd->command == '_log_') { $tail_n = isset($cur_cmd->params[0]) ? (int) $cur_cmd->params[0] : 10; if (file_exists($log_file)) { $log_data = `tail -n {$tail_n} {$log_file}`; } fwrite($rec_socket, json_encode($log_data)); continue; } elseif ($cur_cmd->command == '_finished_') { // 进程结束通知 $this->_shell_count--; // 正在运行的进程计数自减 if ($queued_cmd = $this->shiftCmd()) { // 一个进程结束后,判断队列是否有正在等待的命令, // 有则唤起 $cur_cmd = $queued_cmd; } else { // 队列中没有等待命令,忽略 continue; } } else { if ($this->_shell_count >= Flight::conf()->get('cli.sys.maxprocess')) { // 正在运行的进程是否已经达到上限 // 是则插入等待队列,继续等待 $this->pushCmd($cur_cmd); continue; } else { $queued_cmd = $this->shiftCmd(); if (!empty($queued_cmd)) { // 队列中有等待的命令,先处理 $this->pushCmd($cur_cmd); $cur_cmd = $queued_cmd; } else { // 队列中没等待命令 } } } $process_cmd = $this->getProcessCmd($cur_cmd->command, $cur_cmd->params); if (false === $process_cmd) { continue; } $id = Process::fork($cur_cmd->command, $process_cmd['closure'], $process_cmd['params']); $log = date('H:i:s') . " start({$id}):" . json_encode($cur_cmd); $ret = `echo "{$log}" >> {$log_file}`; $this->_runing_list[$id] = $cur_cmd; $this->_spare_time[$id] = microtime(1); $this->_shell_count++; } }