Created
March 5, 2019 20:29
-
-
Save alphp/67f99429b9c76c972199c4051b3c57b6 to your computer and use it in GitHub Desktop.
CakePHP 3 service example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Shell; | |
if (!extension_loaded('win32service')) dl('php_win32service.dll'); | |
use Cake\Core\Configure; | |
use Cake\Console\Shell; | |
use Cake\Log\Log; | |
Log::drop('debug'); | |
Log::drop('error'); | |
Log::config('service', array( | |
'engine' => 'File', | |
'levels' => ['notice', 'info', 'debug', 'warning', 'error', 'critical', 'alert', 'emergency'], | |
'path' => LOGS, | |
'file' => strftime('cake-service-%Y%m%d'), | |
'size' => false, | |
)); | |
class ServiceShell extends Shell { | |
private $service = [ | |
'run_file' => LOGS . '/service_run.log', | |
'loop_wait' => 10, | |
'service' => [ | |
'service' => 'CakePHPServiceShell', | |
'display' => 'CakePHP ServiceShell', | |
'description' => 'Test CakePHP Service', | |
//'user' => '', | |
//'password' => '', | |
'path' => '"cake.cmd"', | |
'params' => 'Service run -q', | |
//'load_order' => '', | |
'svc_type' => WIN32_SERVICE_WIN32_OWN_PROCESS, | |
// WIN32_SERVICE_AUTO_START | WIN32_SERVICE_DEMAND_START | WIN32_SERVICE_DISABLED | |
//'start_type' => WIN32_SERVICE_AUTO_START, | |
//'error_control' => WIN32_SERVER_ERROR_IGNORE, | |
//'delayed_start' => false, | |
//'base_priority' => '', | |
], | |
]; | |
private $status = null; | |
private $config = null; | |
private $cmd = null; | |
private $commands = ['run', 'create', 'delete', 'stop', 'start', 'debug']; | |
private function write_run ($msg = null) { | |
file_put_contents($this->service['run_file'], date('Y-m-d H:i:s') . $this->nl() . $msg); | |
} | |
public function create () { | |
if (!isset($this->status['CurrentState']) and $this->status == WIN32_ERROR_SERVICE_DOES_NOT_EXIST) { | |
$this->log('Creating service', 'warning'); | |
$this->win32_op_service('win32_create_service', $this->service['service'], WIN32_NO_ERROR, 'Service created', 'debug'); | |
} | |
} | |
public function delete () { | |
if (isset($this->status['CurrentState']) and $this->status['CurrentState'] == WIN32_SERVICE_STOPPED) { | |
$this->log('Deleting service', 'warning'); | |
$this->win32_op_service('win32_delete_service', $this->service['service']['service'], WIN32_NO_ERROR, 'Service deleted', 'debug'); | |
} | |
} | |
public function stop () { | |
if (isset($this->status['CurrentState']) and $this->status['CurrentState'] == WIN32_SERVICE_RUNNING) { | |
$this->log('Sending stop signal', 'warning'); | |
$this->win32_op_service('win32_stop_service', $this->service['service']['service'], WIN32_NO_ERROR, 'Stop signal sent', 'debug'); | |
} | |
} | |
public function start () { | |
if (isset($this->status['CurrentState']) and $this->status['CurrentState'] == WIN32_SERVICE_STOPPED) { | |
$this->log('Sending start signal', 'warning'); | |
$this->win32_op_service('win32_start_service', $this->service['service']['service'], WIN32_NO_ERROR, 'Start signal sent', 'debug'); | |
} | |
} | |
private function start_service () { | |
$this->log('Connecting with the service', 'info'); | |
if (!$this->win32_op_service('win32_start_service_ctrl_dispatcher', $this->service['service']['service'])) return false; | |
return $this->set_service_running(); | |
} | |
private function set_service_running () { | |
$this->log('Sending running signal', 'warning'); | |
return $this->win32_op_service('win32_set_service_status', WIN32_SERVICE_RUNNING, true, 'Service started', 'info'); | |
} | |
private function set_service_stopped () { | |
$this->log('Sending stopped signal', 'warning'); | |
return $this->win32_op_service('win32_set_service_status', WIN32_SERVICE_STOPPED, true, 'Service stopped', 'info'); | |
} | |
private function win32_op_service ($win32_op_service, $param, $cond = true, $msg = null, $debug = null) { | |
$err_code = $win32_op_service($param); | |
if ($err_code === $cond) { | |
if (isset($msg)) $this->log($msg, $debug); | |
return true; | |
} elseif ($err_code === false) { | |
$this->log('Problem with the parameters', 'error'); | |
} elseif ($err_code === WIN32_ERROR_ACCESS_DENIED) { | |
$this->log('Access denied', 'error'); | |
} else { | |
$this->log('Win32 Error Code ' . $err_code, 'error'); | |
} | |
return false; | |
} | |
private function main_loop ($debug = false) { | |
$this->write_run(); | |
$this->log('Do something', 'info'); | |
} | |
public function run () { | |
if (isset($this->status['CurrentState']) and $this->status['CurrentState'] == WIN32_SERVICE_START_PENDING) { | |
if ($this->start_service()) { | |
while (WIN32_SERVICE_CONTROL_STOP != $ctr_msg = win32_get_last_control_message()) { | |
if ($ctr_msg === WIN32_SERVICE_CONTROL_INTERROGATE) { | |
win32_set_service_status(WIN32_SERVICE_RUNNING); | |
//} elseif ($ctr_msg === WIN32_SERVICE_CONTROL_CONTINUE) { | |
//} elseif ($ctr_msg === WIN32_SERVICE_CONTROL_PAUSE) { | |
//} elseif ($ctr_msg === WIN32_SERVICE_CONTROL_PRESHUTDOWN) { | |
//} elseif ($ctr_msg === WIN32_SERVICE_CONTROL_SHUTDOWN) { | |
//} elseif ($ctr_msg === WIN32_SERVICE_CONTROL_STOP) { | |
} | |
$this->main_loop(); | |
$this->write_run('LOOP WAIT'); | |
sleep($this->service['loop_wait']); | |
} | |
$this->set_service_stopped(); | |
} | |
} | |
} | |
public function startup () { | |
$this->log('Querying service status', 'info'); | |
$this->status = win32_query_service_status($this->service['service']['service']); | |
} | |
public function getOptionParser () { | |
$parser = parent::getOptionParser(); | |
$parser->description('Test Servicio CakePHP.'); | |
$subcommands = []; | |
$subcommands['run']['help'] = ('Ejecuta el bucle del servicio.'); | |
$subcommands['create']['help'] = ('Crea el servicio.'); | |
$subcommands['create']['parser']['description'][] = 'Crea el servicio.'; | |
$subcommands['create']['parser']['description'][] = 'Es necesatiro tener permisos administrativos.'; | |
$subcommands['create']['parser']['epilog'][] = 'Uso:'; | |
$subcommands['create']['parser']['epilog'][] = 'Cake Service create'; | |
$subcommands['delete']['help'] = ('Elimina el servicio.'); | |
$subcommands['delete']['parser']['description'][] = 'Elimina el servicio.'; | |
$subcommands['delete']['parser']['description'][] = 'Es necesatiro tener permisos administrativos.'; | |
$subcommands['delete']['parser']['epilog'][] = 'Uso:'; | |
$subcommands['delete']['parser']['epilog'][] = 'Cake Service delete'; | |
$subcommands['stop']['help'] = ('Detiene el servicio.'); | |
$subcommands['stop']['parser']['description'][] = 'Detiene el servicio.'; | |
$subcommands['stop']['parser']['description'][] = 'Es necesatiro tener permisos administrativos.'; | |
$subcommands['stop']['parser']['epilog'][] = 'Uso:'; | |
$subcommands['stop']['parser']['epilog'][] = 'Cake Service stop'; | |
$subcommands['start']['help'] = ('Inicia el servicio.'); | |
$subcommands['start']['parser']['description'][] = 'Inicia el servicio.'; | |
$subcommands['start']['parser']['description'][] = 'Es necesatiro tener permisos administrativos.'; | |
$subcommands['start']['parser']['epilog'][] = 'Uso:'; | |
$subcommands['start']['parser']['epilog'][] = 'Cake Service start'; | |
$parser->addSubcommands($subcommands); | |
return $parser; | |
} | |
public function welcome () {} | |
public function main () { | |
$this->log($this->status, 'info'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment