Fake server push php help

Hi

New here and a php beginner trying to learn. I recently ran into a file that does fake server push which according to the author it updates image, etc by sending file updates to a browser. what i want to do or tried is to have it update another php file every x seconds but yet to make it work. I have been at it for a few days and only been coming up with errors :mad:. What it does From the author:

This PHP script provides a simple function to enable server push. All you need to do is tell it what file to serve, and update that file whenever a new version is available. The script also provides a JavaScript-based workaround for Internet Explorer (it may have limited success with other browsers), that uses more bandwidth, but at least it works, and avoids the need for the user to install a plugin - a common failed solution to this problem.

The file is in it’s original state so I can see if anyone can help me achieve what I want . Thanks in advance for any help…

<?php

/***************************************************
    Library to provide server push functionality
Version 1.0 - Written by Mark Wilton-Jones 16/7/2008
****************************************************

Please see http://www.howtocreate.co.uk/php/ for details
Please see http://www.howtocreate.co.uk/jslibs/termsOfUse.html for terms and conditions of use

PHP/server requirements:
  * Requires PHP 4.2.0+
  * Cannot be used on servers where PHP flush is disabled, such as those running mod_security, mod_gzip, suPHP, some win32 installs
  * PHP needs to be allowed to set max_execution_time (PHP must not be running in safe mode)
  * PHP needs to be allowed to disable compression, or compression must be disabled by default
  * Server push typically uses a child thread per connection - ensure your server allows enough to cope with all your visitors

PHP API:
void doServerPush( string: file_path, string: MIME_type, int: poll_time_in_ms )
  Serves the specified file, along with any updates, using server push.
  Does not return at all unless ignore_user_abort is forced.
void enableFakeServerPush()
  For use on the page where the pushed content is used
  Creates a JavaScript that can simulate server push in browsers that do not support it (specifically Internet Explorer).
  Reloads the file even if it has not changed, so uses more bandwidth than true server push.

JavaScript API:
void fakeServerPush( object: element, string: property, string: newsrc, int: poll_time_in_ms )
  Every poll, the specified property on the element is set to the newsrc, along with a random query string to prevent caching.
  Waits for the next file to load before waiting for the next poll interval.

Using server push is as simple as this:
  require('serverpush.php');
  doServerPush('some_image.jpg','image/jpeg',1000);
Every time the some_image.jpg file is changed on the filesystem, the update will be sent to the browser.
Recommended poll is 50+ with about 1000 (1 second) or more being normal - poll needs to be long enough to send the file to the
user, and will be affected by the user's network speed.
doServerPush does not attempt to sanitise file paths - the script that calls the doServerPush function must ensure that the file
path it is serving is safe for the user to see.

Using the script to simulate server push in browsers that do not support it, relies on the user having JavaScript enabled:
Somewhere in the document head, include this file then call the enableFakeServerPush function to create the JavaScript.
Then add an onerror event handler to the image tag being used to display the pushed content, which then calls fakeServerPush.
Poll time is not affected by network speed.

Example 1:
  <img src="push_image.php" onerror="fakeServerPush(this,'src','some_image.jpg',1000);" alt="foo">

Example 2 (better fallback - static image - if IE has JS disabled):
  <object src="push_image.php" onerror="fakeServerPush(document.getElementById('ani'),'src','some_image.jpg',1000);">
  <img src="some_image.jpg" id="ani" alt="foo">
  </object>
___________________________________________________________________________________________________________*/

function doServerPush($file,$type,$poll) {

	if( !file_exists($file) ) {
		//on first load, the file must exist, or it ends up sending a broken file
		header('Content-type: text/html',true,404);
	}

	@set_time_limit(0); //PHP must not terminate this script
	@ignore_user_abort(false); //do not ignore user aborts (may not be allowed, so status is checked in the loop)
	@ini_set( 'zlib.output_compression', 'off' );
	$poll *= 1000;

	//need a unique boundary
	//while it is possible to get a unique boundary for the current image data, it is possible that it will conflict
	//with future image data - can't help this, just have to live with it - might as well use a static string
	$separator = 'MTWJ_serverpush_boundary_';
	for( $i = 0, $randChars = Array('A','B'); $i < 20; $i++ ) {
		$separator .= $randChars[rand(0,1)];
	}

	header('Cache-Control: no-cache');
	header('Pragma: no-cache');
	//the header that makes server push work
	header("Content-Type: multipart/x-mixed-replace;boundary=$separator",true);
	$extrabreaks = '';

	do {
		//send one file starting with a multipart boundary
		$filelen = filesize($file);
		print "$extrabreaks--$separator\
";
		if( !$extrabreaks ) { $extrabreaks = "\
\
"; } //Safari needs exactly one blank line, no extra linebreaks on the first one
		print "Content-Type: $type\
";
		print "Content-Length: $filelen\
\
";
		readfile($file);
		//Safari needs 200+ bytes between headers - IE needs 256+ per flush, and this will also take care of that, when IE gets server push
		print str_pad('',200-$filelen); //whitespace here is ignored because of content-length
		$lastupdsate = filemtime($file);
		ob_flush();
		flush();
		$looptime = time();
		do {
			clearstatcache(); //need updated file info
			usleep($poll);
			if( time() - $looptime >= 10 ) {
				//every 10 seconds, force it to re-evaluate if the user has disconnected (connection_aborted does not know until this happens)
				//most use-cases will not need this protection because they will keep trying to send updates, but it is here just in case
				$looptime = time();
				print ' '; //whitespace is ignored at this specific point in the stream
				ob_flush();
				flush();
			}
			//poll the filesystem until the file changes, then send the update
			//the file may not always exist for the instant it is being replaced on the filesystem
			//nested loop and filemtime check inspired by http://web.they.org/software/php-push.php
		} while( !connection_aborted() && ( !file_exists($file) || ( $lastupdsate == filemtime($file) ) ) );
	} while( !connection_aborted() ); //if aborts are ignored, exit anyway to avoid endless threads
}

function enableFakeServerPush() {
	//in theory, it would be possible to reduce bandwidth by making this script use XMLHttpRequest HEAD requests to check if-modified-since
	//(fetching the last update date from JavaScript), but that has numerous flaws:
	// * it only works within the same domain, but most server push is done with images from other domains
	// * not all servers use if-modified-since correctly for dynamic content
	// * not all servers respond correctly to head requests containing if-modified-since
	// * it would rely on the user's computer clock being correct, and a disturbingly large number are not
	// * it over-complicates matters and adds more points of failure, when all that is needed is something that just works
	?>
<script type="text/javascript">
function fakeServerPush(anielem,property,newsrc,poll) {
	if( anielem.alreadyFakePushing ) { return; }
	anielem.alreadyFakePushing = true;
	anielem.onload = function () {
		setTimeout(function () {
			anielem[property] = newsrc + ( ( newsrc.indexOf('?') + 1 ) ? '&' : '?' ) + 'ignorerandom=' + (new Date()).getTime() + '' + Math.random();
		},poll);
	};
	anielem[property] = newsrc + ( ( newsrc.indexOf('?') + 1 ) ? '&' : '?' ) + 'ignorerandom=' + (new Date()).getTime() + '' + Math.random();
}
</script>
	<?php
}

?>

What exactly are you trying to achieve?
And what are the errors that you’re getting?

thanks for the reply.
Basically I was or am trying to push update a certain php file with this one eg data.php. According to the author it updates an image and can be used to push update other types of files. But for some reason I’m not doing something properly. The few methods I tried gave me errors like I said I am a novice php developer. The errors vary depending what I tried to change or add to the file to try to push data.php instead of an image. Thanks for any help…

I am also unclear on what you want to achieve as the END goal here, because there are ways for proper server push (WebSockets), “fake” server push (Comet) but all of these might not be the appropriate tool for the job.

I didn’t bother to read the code, it’s easier to try to determine what’s going wrong from the actual errors that you still have to post.

thanks for the reply.
My goal is to push a php file every x seconds. I found this php file online that says it simulates a fake push server using only php. I understand this can be done using a real push server and or websockets but I didnt want to get to complicated and do it that way yet. I just wanted to see if it was possible that this actual file found online to simulate a fake push server via php without the need for a real push server or even using websockets instead. The errors are most likely I didnt do it right I tried many different ways and like mentioned I am new and learning. All i wanted to see is if anyone here that has much more experience then me to look at that given code and help me push/update a php file instead of an image. That is all I wanted and as said the error’s are mostly like due to my lack of knowledge at this point. If I place this code on top of a file

<?php require('serverpush.php');
  doServerPush?>('data.php',1000);

It doesnt work I get errors and a blank page all together like I said I am doing it wrong and would like to learn what I am doing wrong and how to fix it and make it work the way I would like it to work. The errors would be irrelevant to post because no matter what I do it comes out with different errors and the page comes out blank thats how I know I am doing something completely wrong. If it was a error that displayed and the rest of the page also displayed then I would have posted the error or I might have even fixed it myself. Thanks for any advice and any future help.

How about this instead of using the file I found online. I am currently running or setting a cron job to update a php file ( data.php ) every x minutes. My goal was not to use a cron to update the file ( data.php ) and have or write a another php file that updates/pushes this said php file ( data.php ). The reason why is because certain hosts wont allow cron jobs and yes I know use another host :slight_smile: but instead of doing that I thought if I can accomplish this another way. I am trying to improve the code/site and find other methods to achieve my needs. the file ( data.php ) updates the database of all active users in real time ( live streaming ) so finding a different method would be nice. Eventually later on this will be redone using a push server to handle all the live streaming but as of now I wanted to see if it can be done without the need of a cron, push server, websockets and even using node.js. I understand the way I want to do it now with another php file is not the best but I still wanted to try. I found the above code and hoped it can be used to update the file ( data.php ) without the need of setting the cron job for data.php.

I’ve skimmed trough the code and I’ll try quickly to convince you NOT to use this for what you wanted to achieve :slight_smile:

There are 2 ways to do the push.
First is what is called “Comet”. What it’s about is that users’ browser requests certain URL every X seconds via JavaScript. That’s exactly what this script is trying to do.
HTTP is a protocol in which something requests something and then server replies and that’s the end of the communication.

Syntax for doing basic “fake” push is using JavaScript to request a resource via AJAX method (it’s trivial via jQuery) every X seconds, which seems that it’s exactly what this script is trying to do. setTimeout() is the function that you could check to see how it works.

So, if you have rather busy website, say 10k unique users per day - imagine the load on your server if every single of those users are doing an additional request every 10 seconds while their browser is pointing to your website.
What you have to ask yourself is - is this feature you’re trying to implement really worth the trouble?

The other way is using WebSockets - it’s still unsupported by… well, everything except Chrome as far as I know and you need a server for that too (a simple one can be written in PHP). There are other bits and bobs you need to know about WebSockets but in reality - for production websites it’s out of the question.

So the most resource-saving feature would be a cron job.
However, there’s something in MySQL 5.5 called an Event or temporal trigger.
It’s a task MySQL executes at predefined intervals.
There’s also a MySQL UDF called lib_mysql_udf_sys found at http://www.mysqludf.org/lib_mysqludf_sys/index.php

But the thing is, all of those require certain level of access to the machine running the whole site.
In my opinion, you can either go with this fake push and increase the load on your site or you can actually find a host allowing for cron jobs.
I’m sorry I wasn’t of help with the actual code, truth is I’m very tired at the moment and I’m typing this at the verge of my stamina :slight_smile:

On the other hand, server push is the thing I am really interested in and I had to leave some kind of a comment before passing out :slight_smile:

Thank you soo much for the reply… Believe me I understand everything you said. And truth be told I know that a push server is the right way to go unfortunately I cant do that at this point I dont want to pay for a dedicated server to install a comet server ( APE, Lightstreamer etc ). I was just trying to use something like this code as a testing ground and it will be only me on the site so no heavy loads will be an issue. But thanks for the MySQL Event.Temporal trigger which I will investigate further and see if that would work for me at this point of development. Also I know about websockets and thats why I really payed no attention ( for now ). Again thanks for the advice and even looking at the thread with some feedback. I would be grateful if you or anyone has any idea how I can achieve what I need given all the information. Thanks again and hopefully someone can point me to the right direction or method other then what I mentioned here.

Well if you’re familiar with basics of JavaScript / jQuery - there’s no reason why you wouldn’t be able to create such a script for yourself.

All you need to do is create a file that will send a JSON response, something like:

$someData = array('last_modified' => time());

echo json_encode($someData);

The mentioned file can contain db connection and so on, I used a simple array just for the example.

Then, for the client-side of the thing - you use jQuery for performing requests so you end up with something similar to:


	
function doRequest(url, data)
{
	var retval = '';
	$.ajax({
            type: "POST",
            url: url,
            data : data,
			dataType: 'json',
			async:false,
			cache:false,
            success: function(json){
            	retval = json;
            },
            error: $.rpc._getError
        });
	return retval;
}

And finally, all you need to do is perform the request every X seconds and parse it, so you need:

function doMagicStuff()
{
	var json = request('http://my.website.tld/phpfile.php');
	
	console.log(json);
	
	// or alternatively
	
	alert(json.last_modified);
}

var repeat = doMagicStuff();

setTimeout(repeat, 1000);

And voila, you have your “fake” push that gets executed every second and it retrieves data in JSON format. Now you can do whatever you want with that data, parse it, alert it and so on.