Streaming HTTP(S) through PHP and Javascript with XMLHttpRequest
Introduction
Server-side PHP streaming
Client-side Javascript streaming
Conclusion
Introduction
As was revealed by XHR, the ability to have a dynamically changing page is fairly easy to implement, and is extremely useful for a broad array of applications. However, as was mentioned at the end of XHR, what if we wish to implement instant messaging or such applications that require constant communications?
The answer, as also covered previously, is simply to never close the connection, on both the client and server's sides.
Make note that this does not work under Internet Explorer, and until I figure out why it cannot maintain an asynchronous connection through Microsoft.XMLHTTP or Msxml2.XMLHTTP, it will remain so.
Since we already have a vague idea of what to implement client-side(although it will need to be modified), let us first tackle what will be done server-side, through the use of PHP.
The answer, as also covered previously, is simply to never close the connection, on both the client and server's sides.
Make note that this does not work under Internet Explorer, and until I figure out why it cannot maintain an asynchronous connection through Microsoft.XMLHTTP or Msxml2.XMLHTTP, it will remain so.
Since we already have a vague idea of what to implement client-side(although it will need to be modified), let us first tackle what will be done server-side, through the use of PHP.
Server-side PHP streaming
What must be accomplished on the server side is:
[Receive connection, initialize loop that send data & flushes; closes on client disconnect]
This would be implemented in a manner such as:
live.php
<?php
// First detect browser-type, as some browsers are picky.
if (strstr($_SERVER['HTTP_USER_AGENT'], 'Safari')) {
// Safari required at least 1024 bytes before displaying
echo str_pad('',1024);
$browser = "safari";
}
// Begin our loop that only aborts if the client disconnects
while(!connection_aborted()) {
$i+=3;
// Safari requires a padding of 8 characters
echo ($browser = "safari" ? str_pad($i, 8) : $i);
// Output current data with flush()
flush();
// Sleep for 3 seconds
sleep(3);
}
?>
Now, as can be seen, the downfall of this method is that all information would "pile-up" on the client-side -- it is
possible to account for with some minor client-side checking, however I will not be doing so here.
Client-side Javascript streaming
What must be accomplished on the client side is:
[Call XMLHttpRequest, do not close the connection]--[Make continuous changes based upon new data]
| ^
v |
[Server receives request and begins outputting data at regular intervals]
This requires some of the code as covered in XHR, however with some changes.
nStream.js
// set connection as a global variable
var connection = null
function nStream(url) {
setInterval(nParse, 1000);
if (!/*@cc_on!@*/false) {
connection = new XMLHttpRequest();
} else {
connection = new ActiveXObject("Microsoft.XMLHTTP");
}
connection.open("GET", url, true);
connection.onreadystatechange = function() {
if (connection.readyState == 4) {
alert('connection closed.');
}
}
connection.send(null);
}
oldResponse = null;
function nParse() {
var Response = connection.responseText;
if (Response != oldResponse) {
document.getElementById('change').innerHTML = Response;
}
oldResponse = Response;
}
Now then, one would have something akin to the following on a page located in the same directory as live.php and nSt
ream.js:
<script type="text/javascript" src="nStream.js"></script>
<div id="change">
<a href="javascript:;" onClick="nStream('live.php');">Click to Start</a>
</div>
You should get something similar to:
Conclusion
It should be fairly easy to see how one can reapply much of the code here and utilize it in different applications, be they instant messaging, database monitoring, or any such thing.
There are a few issues, of course, with one of them being the need to constantly have the connection open, as this means that for the server<->client relationship to run, the server must maintain that open connection. This makes it so that one should only use this method if it is truly necessary.
There are a few issues, of course, with one of them being the need to constantly have the connection open, as this means that for the server<->client relationship to run, the server must maintain that open connection. This makes it so that one should only use this method if it is truly necessary.
0.0061841011047363 µs