Skip to content

Commit

Permalink
Remove SSE abort handling (#2188)
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek authored Mar 25, 2024
1 parent 890a347 commit 77741e2
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 62 deletions.
2 changes: 1 addition & 1 deletion demos/basic/header.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
Header::addTo($seg, ['H3 Header', 'size' => 3]);
Header::addTo($seg, ['H4 Header', 'size' => 4]);
Header::addTo($seg, ['H5 Header', 'size' => 5, 'class.dividing' => true]);
View::addTo($seg, ['element' => 'P'])->set('This is a following paragraph of text');
View::addTo($seg, ['element' => 'p'])->set('This is a following paragraph of text');

Header::addTo($seg, ['H1', 'size' => 1, 'subHeader' => 'H1 subheader']);
Header::addTo($seg, ['H5', 'size' => 5, 'subHeader' => 'H5 subheader']);
Expand Down
2 changes: 1 addition & 1 deletion demos/basic/menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
$menu = Menu::addTo($app, ['vertical']);
$i = $menu->addItem();
Header::addTo($i, ['size' => 4])->set('Promotions');
View::addTo($i, ['element' => 'P'])->set('Check out our promotions');
View::addTo($i, ['element' => 'p'])->set('Check out our promotions');

// menu without any item should not show
Menu::addTo($app);
2 changes: 1 addition & 1 deletion src/CardDeck.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ protected function init(): void

protected function addMenuBarSearch(): void
{
$view = View::addTo($this->menu->addMenuRight()->addItem()->setElement('div'));
$view = View::addTo($this->menu->addMenuRight()->addItem());

$this->search = $view->add(Factory::factory($this->search, ['context' => $this->container]));
$this->search->reload = $this->container;
Expand Down
4 changes: 2 additions & 2 deletions src/Grid.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ protected function init(): void
$menuElementNameCountsBackup = \Closure::bind(fn () => $this->_elementNameCounts, $this->menu, AbstractView::class)();
try {
$menuRight = $this->menu->addMenuRight(); // @phpstan-ignore-line
$menuItemView = View::addTo($menuRight->addItem()->setElement('div'));
$menuItemView = View::addTo($menuRight->addItem());
$quickSearch = JsSearch::addTo($menuItemView);
$this->stickyGet($quickSearch->name . '_q');
$this->menu->removeElement($menuRight->shortName);
Expand Down Expand Up @@ -316,7 +316,7 @@ public function addQuickSearch($fields = [], $hasAutoQuery = false): void
throw new Exception('Unable to add QuickSearch without Menu');
}

$view = View::addTo($this->menu->addMenuRight()->addItem()->setElement('div'));
$view = View::addTo($this->menu->addMenuRight()->addItem());

$this->quickSearch = JsSearch::addTo($view, ['reload' => $this->container, 'autoQuery' => $hasAutoQuery]);
$q = $this->stickyGet($this->quickSearch->name . '_q') ?? '';
Expand Down
87 changes: 33 additions & 54 deletions src/JsSse.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,15 @@ class JsSse extends JsCallback
{
use HookTrait;

/** Executed when user aborted, or disconnect browser, when using this SSE. */
public const HOOK_ABORTED = self::class . '@connectionAborted';

/** @var bool Allows us to fall-back to standard functionality of JsCallback if browser does not support SSE. */
public $browserSupport = false;

/** @var bool Show Loader when doing sse. */
/** @var bool Show Loader when doing SSE. */
public $showLoader = false;

/** @var bool add window.beforeunload listener for closing js EventSource. Off by default. */
public $closeBeforeUnload = false;

/** @var bool Keep execution alive or not if connection is close by user. False mean that execution will stop on user aborted. */
public $keepAlive = false;

/** @var \Closure|null custom function for outputting (instead of echo) */
public $echoFunction;

Expand Down Expand Up @@ -75,6 +69,25 @@ public function set($fx = null, $args = null)
});
}

protected function initSse(): void
{
$this->getApp()->setResponseHeader('content-type', 'text/event-stream');

// disable buffering for nginx, see https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers
$this->getApp()->setResponseHeader('x-accel-buffering', 'no');

// disable compression
@ini_set('zlib.output_compression', '0');
if (function_exists('apache_setenv')) {
@apache_setenv('no-gzip', '1');
}

// prevent buffering
while (ob_get_level() > 0) {
ob_end_flush();
}
}

/**
* Sending an SSE action.
*/
Expand Down Expand Up @@ -119,11 +132,13 @@ public function sendEvent(string $id, string $data, ?string $eventName = null):
}

/**
* Send Data in buffer to client.
* Create SSE data string.
*/
public function flush(): void
private function wrapData(string $string): string
{
flush();
return implode('', array_map(static function (string $v): string {
return 'data: ' . $v . "\n";
}, preg_split('~\r?\n|\r~', $string)));
}

private function output(string $content): void
Expand All @@ -141,57 +156,21 @@ private function output(string $content): void
}, null, $app)();
}

public function sendBlock(string $id, string $data, ?string $eventName = null): void
/**
* Send Data in buffer to client.
*/
public function flush(): void
{
if (connection_aborted()) {
$this->hook(self::HOOK_ABORTED);

// stop execution when aborted if not keepAlive
if (!$this->keepAlive) {
$this->getApp()->callExit();
}
}
flush();
}

public function sendBlock(string $id, string $data, ?string $eventName = null): void
{
$this->output('id: ' . $id . "\n");
if ($eventName !== null) {
$this->output('event: ' . $eventName . "\n");
}
$this->output($this->wrapData($data) . "\n");
$this->flush();
}

/**
* Create SSE data string.
*/
private function wrapData(string $string): string
{
return implode('', array_map(static function (string $v): string {
return 'data: ' . $v . "\n";
}, preg_split('~\r?\n|\r~', $string)));
}

/**
* It will ignore user abort by default.
*/
protected function initSse(): void
{
@set_time_limit(0); // disable time limit
ignore_user_abort(true);

$this->getApp()->setResponseHeader('content-type', 'text/event-stream');

// disable buffering for nginx, see https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers
$this->getApp()->setResponseHeader('x-accel-buffering', 'no');

// disable compression
@ini_set('zlib.output_compression', '0');
if (function_exists('apache_setenv')) {
@apache_setenv('no-gzip', '1');
}

// prevent buffering
while (ob_get_level() > 0) {
ob_end_flush();
}
}
}
9 changes: 6 additions & 3 deletions tests/DemosTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ class DemosTest extends TestCase
|(?<string>"([^"\\\]*|\\\["\\\bfnrt/]|\\\u[0-9a-f]{4})*")
|(?<array>\[(?:(?&json)(?:,(?&json))*|\s*)\])
|(?<object>\{(?:(?<pair>\s*(?&string)\s*:(?&json))(?:,(?&pair))*|\s*)\})
)\s*)$~six';
protected static string $regexSseLine = '~^(id|event|data).*$~s';
)\s*)$~sx';
protected static string $regexSseLine = '~^(id|event|data): .*$~';

#[\Override]
public static function setUpBeforeClass(): void
Expand Down Expand Up @@ -448,7 +448,10 @@ public function testDemoSseResponse(string $path): void
$response = $this->getResponseFromRequest($path);
self::assertSame(200, $response->getStatusCode());

$outputLines = preg_split('~\r?\n|\r~', $response->getBody()->getContents(), -1, \PREG_SPLIT_NO_EMPTY);
$outputLines = array_filter(
explode("\n", $response->getBody()->getContents()),
static fn ($v) => $v !== ''
);

// check SSE Syntax
self::assertGreaterThan(0, count($outputLines));
Expand Down

0 comments on commit 77741e2

Please sign in to comment.