'How to set up Server-Sent Events with Modx/Evolution CMS? Without blocking the entire CMS?
I am using Evolution CMS (Modx) and would like to set up one resource (document) that outputs SSE (server-sent events).
I have set the ContentType of the document to text/event-stream.
My PHP script (snippet) looks like this:
<?php
@ini_set('output_buffering', 0);
@ini_set('zlib.output_compression', 0);
@ini_set('implicit_flush', 1);
@ini_set('proxy_buffering', 0);
// REMOVE all previous set headers (by EvoCMS)
header_remove();
// header("Connection: Keep-alive");
header('Content-Type: text/event-stream; charset=UTF-8');
header('Cache-Control: no-cache');
header('X-Accel-Buffering: no'); // disable FastCGI Buffering on Nginx
$counter = 0;
$maxexecution = 15;
// keep the script running
while (true)
{
// connection is aborted at client side
if (connection_aborted())
{
break;
}
$counter++;
if ($counter % 2 == 0)
{
// Send a random message every 2s
echo "data: I counted ".$counter."\n\n";
// IMPORTANT: this is for the buffer achieve the minimum size in order to flush data
echo str_pad(' ', 4096)."\n";
// send Data in the output buffer buffer to client.
// ob_end_flush();
ob_flush(); // sends output data from PHP to Apache
flush(); // sends output from Apache to browser
}
if ($counter > $maxexecution)
{
// stop while and close connection
echo "data: SERVER STOPPED\n\n";
flush();
break;
}
sleep(1);
}
return;
Still, the output only appears after 15 seconds (full script execution time).
If I run the script independent from EVO CMS, it works. The output appears every 2 seconds in the receiving HTML document.
I thought header_remove(); would be the solution, but maybe some GZIP or other mechanism takes place? If so, how to disable this and output only this snippet? What things is EVO CMS adding that I have to remove?
Update:
I could trigger the output every 2 seconds when using ob_end_flush(). However, now I get the error that the headers have been sent already.
Error : Cannot modify header information - headers already sent by (output started at /core/src/Core.php(1867) : eval()'d code:87)
How do I prevent Evolution CMS to sent headers?
And it is confusing that I set text/eventstream but get the JS error: EventSource's response has a MIME type ("text/html") that is not "text/event-stream". Aborting the connection.
Update 2:
I could fix this by adding an exit() at the end of the snippet (after the while loop).
However, when the browser is listening to the SSE, it seems that I cannot navigate the website (CMS) anymore. It seems that this snippet processing is blocking all other interactions.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
