Viktor Joras
Viktor Joras

Reputation: 783

Broadcast stream with PHP within localhost

Maybe I'm asking the impossible but I wanted to clone a stream multiple times. A sort of multicast emulation. The idea is to write every 0.002 seconds a 1300 bytes big buffer into a .sock file (instead of IP:port to avoid overheading) and then to read from other scripts the same .sock file multiple times. Doing it through a regular file is not doable. It works only within the same script that generates the buffer file and then echos it. The other scripts will misread it badly.

This works perfectly with the script that generates the chunks:

$handle = @fopen($url, 'rb');

$buffer = 1300;

while (1) {
            $chunck = fread($handle, $buffer);

            $handle2 = fopen('/var/tmp/stream_chunck.tmp', 'w');

            fwrite($handle2, $chunck);

            fclose($handle2);

            readfile('/var/tmp/stream_chunck.tmp');
}

BUT the output of another script that reads the chunks:

while (1) {
                readfile('/var/tmp/stream_chunck.tmp');
}

is messy. I don't know how to synchronize the reading process of chunks and I thought that sockets could make a miracle.

Upvotes: 2

Views: 493

Answers (1)

symcbean
symcbean

Reputation: 48387

It works only within the same script that generates the buffer file and then echos it. The other scripts will misread it badly

Using a single file without any sort of flow control shouldn't be a problem - tail -F does just that. The disadvantage is that the data will just accululate indefinitely on the filesystem as long as a single client has an open file handle (even if you truncate the file).

But if you're writing chunks, then write each chunk to a different file (using an atomic write mechanism) then everyone can read it by polling for available files....

do {
   while (!file_exists("$dir/$prefix.$current_chunk")) {
     clearstatcache();
     usleep(1000);
   }
   process(file_get_contents("$dir/$prefix.$current_chunk"));
   $current_chunk++;
} while (!$finished);

Equally, you could this with a database - which should have slightly lower overhead for the polling, and simplifies the garbage collection of old chunks.

But this is all about how to make your solution workable - it doesn't really address the problem you are trying to solve. If we knew what you were trying to achieve then we might be able to advise on a more appropriate solution - e.g. if it's a chat application, video broadcast, something else....

I suspect a more appropriate solution would be to use mutli-processing, single memory model server - and when we're talking about PHP (which doesn't really do threading very well) that means an event based/asynchronous server. There's a bit more involved than simply calling socket_select() but there are some good scripts available which do most of the complicated stuff for you.

Upvotes: 1

Related Questions