92 lines
2.7 KiB
PHP
92 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace NoccyLabs\Mercureact;
|
|
|
|
use Monolog\Handler\StreamHandler;
|
|
use Monolog\Level;
|
|
use Monolog\Logger;
|
|
use NoccyLabs\Mercureact\Http\Server;
|
|
use Psr\Log\LoggerInterface;
|
|
use React\EventLoop\Loop;
|
|
use React\EventLoop\LoopInterface;
|
|
use React\Socket\SecureServer;
|
|
use React\Socket\SocketServer;
|
|
use React\Socket\TcpServer;
|
|
|
|
class Daemon
|
|
{
|
|
private Configuration $config;
|
|
|
|
private LoopInterface $loop;
|
|
|
|
private Server $server;
|
|
|
|
private Logger $logger;
|
|
|
|
public function __construct(Configuration $config, bool $verbose=false, ?LoopInterface $loop=null)
|
|
{
|
|
if (!defined("MERCUREACT_VERSION")) define("MERCUREACT_VERSION", "0.0.0");
|
|
$this->config = $config;
|
|
$this->loop = $loop??Loop::get();
|
|
$this->logger = $this->createLogger($verbose);
|
|
}
|
|
|
|
private function createLogger(bool $verbose): Logger
|
|
{
|
|
$handlers = [
|
|
new StreamHandler(STDOUT, $verbose?Level::Debug:Level::Info)
|
|
];
|
|
$logger = new Logger("main", $handlers);
|
|
return $logger;
|
|
}
|
|
|
|
public function start(): void
|
|
{
|
|
$this->server = new Server($this->config, $this->logger, $this->loop);
|
|
|
|
$this->logger->info("Starting NoccyLabs Mercureact Daemon v".MERCUREACT_VERSION." (".MERCUREACT_BUILDTIME.")");
|
|
|
|
$listenAddress = $this->config->getListenAddress();
|
|
if (!$listenAddress) {
|
|
$this->logger->warning("Empty listening address. You won't make it far.");
|
|
return;
|
|
}
|
|
|
|
$certificate = $this->config->get("server.encryption.local_cert");
|
|
|
|
if ($certificate) {
|
|
$this->logger->warning("SSL/TLS suport is broken.");
|
|
$this->logger->info("Using local cert: {$certificate}");
|
|
$context = $this->config->get("server.encryption.");
|
|
$uri = 'tls://' . $listenAddress;
|
|
$context['crypto_method'] = STREAM_CRYPTO_METHOD_TLSv1_3_SERVER;
|
|
$socket = new TcpServer($listenAddress);
|
|
$socket = new SecureServer($socket, null, $context??[]);
|
|
} else {
|
|
$uri = 'tcp://' . $listenAddress;
|
|
$context = [];
|
|
$socket = new SocketServer($uri);
|
|
}
|
|
|
|
|
|
$this->server->listen($socket);
|
|
}
|
|
|
|
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);
|
|
});
|
|
}
|
|
}
|
|
|