SSE incredibly slow
Three problems I see with your code:
- No sleep
- No ob_flush
- Sessions
Your while() loop is constantly reading the file system. You need to slow it down. I've put a half second sleep in the below; experiment with the largest value for acceptable latency.
PHP has its own output buffers. You use @ob_flush()
to flush them (the @
suppresses errors) and flush()
to flush the Apache buffers. Both are needed, and the order is important, too.
Finally, PHP sessions lock, so if your clients might be sending session cookies, even if your SSE script does not use the session data, you must close the session before entering the infinite loop.
I've added all three of those changes to your code, below.
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
session_write_close();
while(1)
{
$data = file_get_contents("data.txt");
if ($data != "NULL")
{
echo "data: " . $data . "\n\n";
@ob_flush();flush();
file_put_contents("data.txt", "NULL");
}
usleep(500000);
}
BTW, the advice in the other answer about using an in-memory database is good, but the file system overhead is in milliseconds, so it won't explain a "30 second to 10 minute" latency.
I don't know that writing to a flat file is the best way to do this. File I/O is going to be your big bottleneck here (reading on top of writing means you'll reach that max really quick). But assuming you want to keep on doing it...
Your application could benefit from a PHP session, to store some data so you're not waiting on I/O. This is where an intermediate software like Memcached or Redis could also help you. What you would do is store the data from reciver.php
in your text file AND write it into memory cache (or put it into your session which writes to the memory store). This makes retrieval very quick and reduces file I/O.
I would highly suggest a database for your data tho. MySQL in particular will load commonly accessed data into memory to speed read operations.