clrghouz/app/Console/Commands/ServerStart.php

129 lines
2.9 KiB
PHP
Raw Normal View History

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
2023-04-22 11:30:30 +00:00
use App\Classes\Protocol\{Binkp,DNS,EMSI};
2023-07-31 09:14:27 +00:00
use App\Classes\Sock\{SocketException,SocketServer};
use App\Models\Setup;
class ServerStart extends Command
{
private const LOGKEY = 'CSS';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'server:start';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Start Server';
/**
* Execute the console command.
*
* @return void
2023-07-31 09:14:27 +00:00
* @throws SocketException
*/
public function handle()
{
2021-08-22 06:55:39 +00:00
Log::info(sprintf('%s:+ Server Starting (%d)',self::LOGKEY,getmypid()));
$o = Setup::findOrFail(config('app.id'));
2021-08-14 04:10:29 +00:00
$start = collect();
if ($o->binkp_active)
2021-08-14 04:10:29 +00:00
$start->put('binkp',[
'address'=>$o->binkp_bind,
'port'=>$o->binkp_port,
2023-04-22 11:30:30 +00:00
'proto'=>SOCK_STREAM,
2021-07-02 13:44:01 +00:00
'class'=>new Binkp($o),
2021-08-14 04:10:29 +00:00
]);
if ($o->emsi_active)
2021-08-14 04:10:29 +00:00
$start->put('emsi',[
2023-07-31 09:14:27 +00:00
'address'=>$o->emsi_bind,
'port'=>$o->emsi_port,
2023-04-22 11:30:30 +00:00
'proto'=>SOCK_STREAM,
2021-08-14 04:10:29 +00:00
'class'=>new EMSI($o),
]);
if ($o->dns_active)
2023-04-22 11:30:30 +00:00
$start->put('dns',[
2023-07-31 09:14:27 +00:00
'address'=>$o->dns_bind,
'port'=>$o->dns_port,
2023-04-22 11:30:30 +00:00
'proto'=>SOCK_DGRAM,
'class'=>new DNS(),
]);
$children = collect();
Log::debug(sprintf('%s:# Servers [%d]',self::LOGKEY,$start->count()));
2021-08-14 04:10:29 +00:00
if (! $start->count()) {
2023-07-19 00:35:29 +00:00
Log::alert(sprintf('%s:! No servers configured to start',self::LOGKEY));
2021-08-14 04:10:29 +00:00
return;
}
2021-07-19 14:23:41 +00:00
pcntl_signal(SIGCHLD,SIG_IGN);
foreach ($start as $item => $config) {
2023-07-19 00:35:29 +00:00
Log::debug(sprintf('%s:- Starting [%s] (%d)',self::LOGKEY,$item,getmypid()));
$pid = pcntl_fork();
2023-06-27 07:39:11 +00:00
if ($pid === -1)
die('could not fork');
// We are the child
if (! $pid) {
Log::withContext(['pid'=>getmypid()]);
2023-07-19 00:35:29 +00:00
Log::info(sprintf('%s:= Started [%s]',self::LOGKEY,$item));
2023-04-22 11:30:30 +00:00
$server = new SocketServer($config['port'],$config['address'],$config['proto']);
$server->handler = [$config['class'],'onConnect'];
try {
$server->listen();
} catch (SocketException $e) {
2023-06-27 07:39:11 +00:00
if ($e->getMessage() === 'Can\'t accept connections: "Success"')
Log::debug(sprintf('%s:! Server Terminated [%s]',self::LOGKEY,$item));
else
Log::emergency(sprintf('%s:! Uncaught Message: %s',self::LOGKEY,$e->getMessage()));
}
2023-07-19 00:35:29 +00:00
Log::info(sprintf('%s:= Finished: [%s]',self::LOGKEY,$item));
// Child finished we need to get out of this loop.
exit;
}
2023-07-19 00:35:29 +00:00
Log::debug(sprintf('%s:- Forked for [%s] (%d)',self::LOGKEY,$item,$pid));
$children->put($pid,$item);
}
// Wait for children to exit
2021-08-14 04:10:29 +00:00
while ($x=$children->count()) {
// Wait for children to finish
$exited = pcntl_wait($status);
2021-08-14 04:10:29 +00:00
if ($exited < 0)
abort(500,'Something strange for status: '.serialize($status));
2023-07-19 00:35:29 +00:00
Log::info(sprintf('%s:= Exited: #%d [%s]',self::LOGKEY,$x,$children->pull($exited)));
}
// Done
Log::debug(sprintf('%s:= Finished.',self::LOGKEY));
}
2023-07-31 09:14:27 +00:00
}