2024-03-10 02:06:19 +00:00
< ? php
namespace NoccyLabs\Mercureact ;
2024-03-12 00:13:19 +00:00
use Monolog\Handler\StreamHandler ;
2024-03-12 01:21:42 +00:00
use Monolog\Level ;
2024-03-12 00:13:19 +00:00
use Monolog\Logger ;
2024-03-10 02:06:19 +00:00
use NoccyLabs\Mercureact\Http\Server ;
2024-03-12 00:13:19 +00:00
use Psr\Log\LoggerInterface ;
2024-03-10 02:06:19 +00:00
use React\EventLoop\Loop ;
use React\EventLoop\LoopInterface ;
2024-03-12 14:51:50 +00:00
use React\Socket\SecureServer ;
2024-03-10 02:06:19 +00:00
use React\Socket\SocketServer ;
2024-03-13 00:28:14 +00:00
use React\Socket\TcpServer ;
2024-03-10 02:06:19 +00:00
class Daemon
{
private Configuration $config ;
private LoopInterface $loop ;
private Server $server ;
2024-03-13 00:28:14 +00:00
private Logger $logger ;
2024-03-12 00:13:19 +00:00
2024-03-12 01:21:42 +00:00
public function __construct ( Configuration $config , bool $verbose = false , ? LoopInterface $loop = null )
2024-03-10 02:06:19 +00:00
{
2024-03-13 00:28:14 +00:00
if ( ! defined ( " MERCUREACT_VERSION " )) define ( " MERCUREACT_VERSION " , " 0.0.0 " );
2024-03-10 02:06:19 +00:00
$this -> config = $config ;
$this -> loop = $loop ? ? Loop :: get ();
2024-03-12 01:21:42 +00:00
$this -> logger = $this -> createLogger ( $verbose );
2024-03-12 00:13:19 +00:00
}
2024-03-12 01:21:42 +00:00
private function createLogger ( bool $verbose ) : Logger
2024-03-12 00:13:19 +00:00
{
$handlers = [
2024-03-12 01:21:42 +00:00
new StreamHandler ( STDOUT , $verbose ? Level :: Debug : Level :: Info )
2024-03-12 00:13:19 +00:00
];
$logger = new Logger ( " main " , $handlers );
return $logger ;
2024-03-10 02:06:19 +00:00
}
public function start () : void
{
2024-03-12 00:13:19 +00:00
$this -> server = new Server ( $this -> config , $this -> logger , $this -> loop );
2024-03-13 00:28:14 +00:00
$this -> logger -> info ( " Starting NoccyLabs Mercureact Daemon v " . MERCUREACT_VERSION . " ( " . MERCUREACT_BUILDTIME . " ) " );
2024-03-10 02:06:19 +00:00
2024-03-11 23:28:31 +00:00
$listenAddress = $this -> config -> getListenAddress ();
if ( ! $listenAddress ) {
2024-03-12 00:13:19 +00:00
$this -> logger -> warning ( " Empty listening address. You won't make it far. " );
2024-03-11 23:28:31 +00:00
return ;
2024-03-11 21:12:01 +00:00
}
2024-03-12 14:51:50 +00:00
$certificate = $this -> config -> get ( " server.encryption.local_cert " );
if ( $certificate ) {
2024-03-13 00:28:14 +00:00
$this -> logger -> warning ( " SSL/TLS suport is broken. " );
2024-03-12 14:51:50 +00:00
$this -> logger -> info ( " Using local cert: { $certificate } " );
2024-03-13 00:28:14 +00:00
$context = $this -> config -> get ( " server.encryption. " );
2024-03-12 14:51:50 +00:00
$uri = 'tls://' . $listenAddress ;
2024-03-13 00:28:14 +00:00
$context [ 'crypto_method' ] = STREAM_CRYPTO_METHOD_TLSv1_3_SERVER ;
$socket = new TcpServer ( $listenAddress );
$socket = new SecureServer ( $socket , null , $context ? ? []);
2024-03-12 14:51:50 +00:00
} else {
$uri = 'tcp://' . $listenAddress ;
2024-03-13 00:28:14 +00:00
$context = [];
$socket = new SocketServer ( $uri );
2024-03-12 14:51:50 +00:00
}
2024-03-11 23:28:31 +00:00
$this -> server -> listen ( $socket );
2024-03-10 02:06:19 +00:00
}
public function stop () : void
{
$this -> loop -> stop ();
}
public function abort ( int $exitcode , ? string $message = null ) : void
{
$bt = debug_backtrace ( limit : 2 );
$bt = end ( $bt );
fprintf ( STDERR , " Abort: %s \n at %s:%d \n in %s \n " , $message ? ? " Unknown reason " , $bt [ 'file' ], $bt [ 'line' ], ( $bt [ 'class' ] ? ? null ) . ( $bt [ 'type' ] ? ? null ) . $bt [ 'function' ]);
$this -> loop -> stop ();
register_shutdown_function ( function () use ( $exitcode ) {
exit ( $exitcode );
});
}
}