44
common/SSR/RenderPageWithNode.php
Executable file
44
common/SSR/RenderPageWithNode.php
Executable file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Common\SSR;
|
||||
|
||||
use Common\ServerTiming\ServerTiming;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class RenderPageWithNode
|
||||
{
|
||||
public function execute(array $bootstrapData): ?string
|
||||
{
|
||||
if (
|
||||
!config('common.site.ssr_enabled') ||
|
||||
request('appearanceEditor') === 'true'
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$serverUrl = config('common.site.ssr_url') . '/render';
|
||||
|
||||
try {
|
||||
app(ServerTiming::class)->start('SSR');
|
||||
$response = Http::withHeaders([
|
||||
'Accept-encoding' => 'gzip',
|
||||
])
|
||||
->post($serverUrl, [
|
||||
'bootstrapData' => $bootstrapData,
|
||||
'url' => request()->getRequestUri(),
|
||||
])
|
||||
->throw()
|
||||
->body();
|
||||
app(ServerTiming::class)->stop('SSR');
|
||||
} catch (Exception $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_null($response)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
9
common/SSR/SsrException.php
Executable file
9
common/SSR/SsrException.php
Executable file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Common\SSR;
|
||||
|
||||
use Exception;
|
||||
|
||||
class SsrException extends Exception
|
||||
{
|
||||
}
|
||||
54
common/SSR/StartSsr.php
Executable file
54
common/SSR/StartSsr.php
Executable file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Common\SSR;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
class StartSsr extends Command
|
||||
{
|
||||
protected $name = 'ssr:start';
|
||||
protected $description = 'Start the SSR server';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
if (!config('common.site.ssr_enabled', true)) {
|
||||
$this->error('SSR is not enabled.');
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->callSilently('ssr:stop');
|
||||
|
||||
$port = parse_url(config('common.site.ssr_url'), PHP_URL_PORT);
|
||||
$process = new Process(
|
||||
['node', base_path('bootstrap/ssr/server-entry.mjs'), "port=$port"],
|
||||
null,
|
||||
[
|
||||
'NODE_ENV' => 'production',
|
||||
],
|
||||
);
|
||||
$process->setTimeout(null);
|
||||
$process->start();
|
||||
|
||||
if (extension_loaded('pcntl')) {
|
||||
$stop = function () use ($process) {
|
||||
$process->stop();
|
||||
};
|
||||
pcntl_async_signals(true);
|
||||
pcntl_signal(SIGINT, $stop);
|
||||
pcntl_signal(SIGQUIT, $stop);
|
||||
pcntl_signal(SIGTERM, $stop);
|
||||
}
|
||||
|
||||
foreach ($process as $type => $data) {
|
||||
if ($process::OUT === $type) {
|
||||
$this->info(trim($data));
|
||||
} else {
|
||||
$this->error(trim($data));
|
||||
report(new SsrException($data));
|
||||
}
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
34
common/SSR/StopSsr.php
Executable file
34
common/SSR/StopSsr.php
Executable file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Common\SSR;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class StopSsr extends Command
|
||||
{
|
||||
protected $name = 'ssr:stop';
|
||||
protected $description = 'Stop the SSR server';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$serverUrl = config('common.site.ssr_url') . '/shutdown';
|
||||
|
||||
$ch = curl_init($serverUrl);
|
||||
curl_exec($ch);
|
||||
|
||||
if (
|
||||
curl_error($ch) !== '' &&
|
||||
curl_error($ch) !== 'Empty reply from server'
|
||||
) {
|
||||
$this->error('Unable to connect to SSR server.');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->info('SSR server stopped.');
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user