4. Client / Server Architecture
A web application uses the traditional Client /
Server architecture:
■ The Client gathers information from the user
and asks the server a service
■ The Server receives a request for information
from the client and servs the requested
information to it
Giacomo Fazio - 2011 4
5. Client / Server Architecture
■ At first, all the Web pages were static: the user asked
for a page and the server returned it
■ Internet was used especially for research and in the
universities, so static pages were enough
■ So there was a 2-tier architecture, where the client
was composed by a web browser (which asks the
server a page) and by the HTML document received
from the server
■ Soon Internet spread in other fields, such as
commerce
■ More dynamic pages were needed, to store data
permanently and to make the user interact with the
website
■ The 2-tier architecture was not sufficient anymore
Giacomo Fazio - 2011 5
6. Client / Server Architecture
Sometimes there is still a 2-tier architecture, but now we
have often a 3-tier (or multi-tier) client/server system,
which consists of three distinct pieces:
■ Client tier (or user interface tier or presentation tier),
composed by a web browser (which asks the server a
page) and by the HTML document received from the
server.
■ Processing tier (or middle tier), that receives a
request from the client tier, handles it, communicates
with the data storage tier and answers the client tier.
It's composed by a web server (ex. Apache, IIS).
■ Data storage tier, which stores data in a database
and receives the requests from the processing tier,
answering to it (ex. MySQL).
Giacomo Fazio - 2011 6
8. Client / Server Architecture
The 3 tiers could stay all in the same
machine, but they are usually divided in
different machines that could be very far
from each other:
■ The client tier is on the user's pc or
smartphone.
■ The processing tier and the data
storage tier are in the same computer
or in different computers.
Giacomo Fazio - 2011 8
9. LAMPP
One of the most powerful development models for the Web is
the ”LAMP”:
■ Linux
■ Apache
■ MySQL
■ PHP and/or Perl and/or Python
Apache is the MySQL is a very PHP / Perl is a
Linux is the free
industry-leading popular general purpose
and open-source
web server that database that scripting
operating system
runs a majority runs on most environment
that runs on
of web servers operating widely used for
most servers
on the Internet. systems. building dynamic
web sites.
If you want to install a LAMP stack on your
machine, you can try XAMPP, an easy to install
Apache distribution that contains PHP, Perl and
MySQL and is available for the most used operating
systems.
Giacomo Fazio - 2011 9
10. Server / Client side technologies
■ We said webpages are now dynamic
■ Classic HTML is not enough, we have to
use other technologies
■ The technologies used to make a
webpage dynamic can be classified in
server-side and client-side technologies
■ Server-side technologies work on the
processing tier
■ Client-side technologies work on the
client-tier
Giacomo Fazio - 2011 10
11. Server / Client side technologies
Web technologies
Server-side scripting Client-side scripting
Compiled Server-side Programs compiled Client-side
programs scripts on the client scripts
CGI Java Applets Javascript
PHP
Java Servlets ASP VBScript
ASP.NET Cold Fusion
Hybrid technologies
Java Server Pages
ASP.NET
Giacomo Fazio - 2011 11
12. Server-side technologies
■ Executed on the server side
■ It allows the creation of pages that are not actually on
the server when asked from the browser, they are
created and composed dynamically from the server,
eventually using the data storage tier
■ It offers more complex and advanced capabilities, as well
as the data storage
■ The code remains hidden from the clients
■ Browser- and client-independent
■ It allows secure access to databases
■ Interactivity is not as immediate as the client-side scripting,
since it's the server who executes the program.
■ Many technologies: CGI, SSI, Servlets, JSP, PHP, ASP,
ASP .NET, Perl, Ruby on Rails, etc.
■ From now on, we will deal with PHP, but many aspects
work the same way in other languages, and translating the
code is usually quite easy.
Giacomo Fazio - 2011 12
13. Server-side technologies: web forms
■ A typical example of use of server-side programming
are the Web forms: data are inserted in a HTML page,
they are then submitted to a server-side page which
can use data for example saving them into a database
Giacomo Fazio - 2011 13
15. Client-side technologies
■ Runs on the local browser
■ Creates visual effects such as
animations (ex. rollover on the buttons)
■ Changes the contents of a Web page
after a browser has rendered it
■ Controls the Web browser window itself
■ Provides immediate feedback to the
user
■ Turns static Web pages into
applications
Giacomo Fazio - 2011 15
16. Client-side technologies
■ Reduces the load on a server: maintaining
state, filling out forms, error checking, or
performing numeric calculation, can be handled
by the client's own computer.
■ Reduces network traffic
■ A script can behave differently on different
browsers
■ Code is viewable by user
■ Sometimes requires additional knowledge of
DHTML and DOM (Document Object Model)
■ Many technologies: JavaScript, VBScript,
Applets, etc.
Giacomo Fazio - 2011 16
17. DHTML (Dynamic HTML)
■ DHTML is a term that indicates a combination
of HTML and client-side technologies that
produces dynamic documents
■ DHTML uses HTML/XHTML, style sheets
(CSS), and client-side scripting to create simple
animations, images, and text that change as a
mouse moves over them
■ DHTML allows more interactivity with visitors to
a Web site
■ DHTML also allows Web pages to behave more
like desktop applications
Giacomo Fazio - 2011 17
18. The DOM (Document Object Model)
■ A W3C standard
■ Describes how the document object can
be traversed and modified
■ Represented as tree structure
■ Can add new elements to the page
■ Can change attributes of existing
elements
■ Client-side languages can work on it
Giacomo Fazio - 2011 18
20. Client-side technologies: JavaScript
■ Interpreted, object-oriented programming language
■ Weakly typed, types are not declared.
■ Introduced by Netscape with Netscape 2.0 in 1995
■ Standardized as ECMAScript by ECMA (European
Computer Manufacturers Association)
■ Not related to Java other than the name
■ Tightly integrated with browser
■ Can handle many types of events generated by the
normal interaction between user and browser
■ Can modify the internal objects based on which the
browser renders the web page
Giacomo Fazio - 2011 20
21. Client-side technologies: JavaScript
■ JavaScript example about events:
<html>
<head>
<script language="JavaScript">
function pushbutton() {
alert("Hello!");
}
</script>
</head>
<body>
<form>
<input type="button" name=“okay" value=“Click me" onclick="pushbutton()">
</form>
</body>
</html>
Giacomo Fazio - 2011 21
22. Client-side technologies: JavaScript
■ Some events JavaScript can handle:
Handler Triggered when Comments
onclick Mouse click on element Return false to cancel default action
onchange The control’s state changes
onfocus The control gets focus
onsubmit The form is submitted Specific to forms
onmouseover Mouse moves over el.
onmouseout Mouse moves off el.
onmousedown Mouse button pressed
onmouseup Mouse button released
onkeydown Key pressed down Used for form elements and <body>
onkeypress Key pressed and released Return false to cancel
onkeyup Key released Used for form elements and <body>
onload Document load complete Used for <body> and <img>
Giacomo Fazio - 2011 22
23. Client-side technologies: JavaScript
■ JavaScript examples:
<input type="text" name="phone_number" id="phone_number"/>
<script type="text/javascript"> Can walk the DOM
var phone = document.getElementById('phone_number');
phone.value='095738';
phone.disabled=true;
document.images[0].src="http://.../some_other_image.jpg";
</script>
var counter;
for(counter=1; counter<=10; counter++) {
document.writeln("<p>cnt:"+counter+"</p>")
}
… Control flow
var name = prompt("What is your name?");
if(name=="John") document.writeln("Hello.");
else if(name=="Jean") document.writeln("Bonjour.");
else document.writeln("Who are you?");
Giacomo Fazio - 2011 23
24. Server-Side or Client-Side?
If you need to track user information across
several Web pages to create a "Web
application“, you must use server-side
programming.
If you need to interact with server-side
databases, you must use server-side
programming.
If you need to use server variables or check
the capabilities of the user's browser, you must
use server-side programming
In general, server-side programming creates
dynamic web pages
Giacomo Fazio - 2011 24
25. Server-Side or Client-Side?
If you want to have dynamic client forms with
client-side validation, you must use client-side
programming.
If you want your site to have highly interactive
pages, you should use client-side programming.
If you need to provide your client with advanced
functionality that can be created only using
ActiveX controls (or Flash, or …), you must use
client-side programming.
If you want to control the user's browser (i.e., to
turn off the menus), you must use client-side
programming.
So if you want to bring life to the HTML pages,
you must use client-side programming
Giacomo Fazio - 2011 25
26. Server-Side or Client-Side?
Both server-side and client-side
programming, either working together
hand-to-hand or not, enhance web
development by extending server
functionality and at the same time,
enrich our web experience with
interactivity
Giacomo Fazio - 2011 26
27. Introduction to jQuery
■ In the last years the trend is not to use pure
JavaScript, but to use one of the many
frameworks created for it
■ Each framework allows a more rapid
development, allowing the web programmer to
write a code that is often more elegant, secure
and cross browser compatible.
■ There are many frameworks: jQuery,
mooTools, Dojo, Prototype, etc.
■ The most used is jQuery (39% of all sites that
use JavaScript use jQuery)
Giacomo Fazio - 2011 27
28. Introduction to jQuery
■ Use of jQuery and of the other frameworks:
Giacomo Fazio - 2011 28
29. Introduction to jQuery
■ Developed by John Resig at Rochester Institute of
Technology
■ jQuery is a lightweight JavaScript library that emphasizes
interaction between JavaScript and HTML. It was released
in January 2006 at BarCamp NYC by John Resig.
■ jQuery is free, open source software, dual-licensed under
the MIT License and the GNU General Public License.
■ It’s all about simplicity. Why should web developers be
forced to write long, complex, book-length pieces of code
when they want to create simple pieces of interaction?
■ Easy to learn
■ It's tiny, few KB
■ Well documented
■ Cross browser compatibility
Giacomo Fazio - 2011 29
30. Introduction to jQuery
■ What jQuery can do:
Cross browser support and detection
AJAX functions
CSS functions
DOM manipulation
DOM transversal
Attribute manipulation
Event detection and handling
JavaScript animation
Hundreds of plugins for pre-built user interfaces, advanced
animations, form validation, etc
Expandable functionality using custom plugins
Small foot print
■ Starting is easy: download the last ”js” file from jQuery website and
include it in your html file using
<script src="jquery-1.4.2.js" type="text/javascript" charset="utf-8"></script>
then use it instead of (or together with) your Javascript code.
Giacomo Fazio - 2011 30
31. Introduction to jQuery
■ So we don't have anymore to learn pure
JavaScript? It's not that easy: jQuery is
extraordinarily useful, but you'd better
know how JavaScript works and how to
use it correctly.
■ The best way is probably to look for a pair
of good tutorials on JavaScript, study and
practise a bit with it, then use jQuery when
possible: your code will surely benefit from
it
Giacomo Fazio - 2011 31
32. jQuery Core
■ It's the principal component of the
framework
■ It provides the function $().
■ Example:
$('<p>Hello World</p>').appendTo('body');
Giacomo Fazio - 2011 32
33. jQuery selectors
■ They are one of the most important innovations of jQuery, whose aim
is to select HTML elements of the page using tag name, attributes or
their content (similar to CSS selectors)
■ 9 types of selectors:
Basic selectors: used to select elements by their id, tag name and
class;
Hierarchy selectors: used to select elements by the hierarchical
organization of the page;
Basic filters: used to filter elements according to their position and
order in the page;
Content filters: used to filter elements according to their content;
Visibility filters: used to filter elements according to their visibility
Attribute filters: used to filter elements according to their
attributes;
Child filters: used to filter child elements of an element;
Form selectors: used to select elements according to their usage
in the form;
Form filters: used to select elements of a form according to their
current state.
Giacomo Fazio - 2011 33
34. jQuery attributes management
■ As in JavaScript, jQuery allows the user to add,
modify and delete the attributes of the HTML
elements.
■ Example:
$('a.google').attr('href','http://www.google.com');
$('a#home').addClass('selected');
alert($('input#name').val());
$('div').text('New content...')
Giacomo Fazio - 2011 35
36. jQuery DOM manipulation
■ jQuery provides some functions whose aim is to
manipulate the DOM: modify the content of the elements,
add, remove and substitute elements in specific points,
etc.
■ Example:
$('body').append(”<div id='container'></div>”);
$('#container').text('Here goes the container text').prepend(”<div id='box'></div>”)
$('#box').text('Here goes the box text').append(”<img src='img.jpg' />”)
<div id='container'>
<div id='box'
Here goes the box text
<img src='img.jpg' />
</div>
Here goes the container text
</div>
Giacomo Fazio - 2011 37
37. jQuery and CSS
■ jQuery allows the user to change the graphical
features of each HTML element of the page.
■ Two ways:
The function css()
helpers that recall particular properties (for
example width() and height()).
■ Example:
$('#img').css('width','50px');
$('#img').width('50px');
Giacomo Fazio - 2011 38
38. jQuery and events
■ jQuery allows the user to associate a callback
function to each event. This function will be
executed when the event occurs.
■ Example:
clkCallback = function() {
alert ('you clicked me');
};
$('div#link').click(clkCallback);
=
$('div#link').click(function() {
alert ('you clicked me');
});
Giacomo Fazio - 2011 39
39. jQuery graphical effects
■ jQuery provides some functions to make your
web application more and more similar to a
desktop application.
■ Beyond the css functions that we have already
seen, we have other functions, such as fade()
and slide().
■ Another good function is animate(), which
allows to create your animation from the
element that has to be animated (height, width,
position) and from the starting value and the
target one.
Giacomo Fazio - 2011 40
40. jQuery and AJAX
What's AJAX? Wait some more slides
;-)
Giacomo Fazio - 2011 41
41. jQuery UI
■ jQuery UI (User Interface) has been started as a
project parallel to jQuery, but it has been then
incorporated into the jQuery development,
becoming the ”jQuery official user interface library”,
even though it has an autonomous development
group
■ Three subcomponents:
Graphical effects (that can be added to the ones
present in jQuery)
Complex interactions (ordering of the elements,
drag and drop, etc)
Widgets (complex controls such as calendars,
modal windows and tabs navigation)
Giacomo Fazio - 2011 42
42. Where can I study jQuery?
■ Start by looking on Google ”jquery tutorial”, you
will find a lot of stuff
■ Look on jquery.com, you will find the
explanation of all the functions and many
examples
■ Look on www.html.it, you will find some good
guides (in italian)
■ If you have time and you like, buy a book on
jQuery (there are many out there)
■ When you have learned well jQuery, start with
jQuery UI if you like
■ Google is your friend ;-)
Giacomo Fazio - 2011 43
43. Limitations of the current model
In general, keep in mind that the process is the
following:
The client asks a server a page
The server retrieves the page
The server executes the server-side code in the
page and obtains so a page that contains HTML
and client-side code
The server returns that page to the client
The browser loads the page returned by the
server
It is possible for the user to exploit the client-
side code to obtain visual effects and in general
to make the web page looks like an application
Giacomo Fazio - 2011 44
44. Limitations of the current model
Anyway, there are lots of limitations:
when a page has been obtained and loaded by the client, you
can't access the server anymore (to do this you have to ask
again the server the page, so you have to repeat the whole
process)
If I have a page with lots of things and I want to update only a
little part (for example stocks trends), I have to reload the whole
page from the server and wait: this causes loss of band and time
and can make the interaction with the user slow and bad
The alternative would be to put the stocks trends on another
page or on a popup window and reload it often, but the result
would be very ugly!
You could also use Iframes, but they don't solve all the
problems, it's not clear if they are deprecated or not and some
programmers tend to consider them a dirty solution
You could use other technologies like Java applets or Flash, but
they usually suffer from some problems, such as heaviness,
proprietary solutions, not cross-browsers or cross-platforms,
need to install other plugins or software, security issues, etc.
Giacomo Fazio - 2011 45
45. Limitations of the current model
This is the model used by ”normal” webpages (totally
sinchronous):
As you can see the client transmits data to the server when
the user requests it. While the server is processing and trying
to return a new web page to the user, the user is left with a
blank screen and a ”still loading” icon in the status bar
Solution: AJAX!!!
Giacomo Fazio - 2011 46
46. AJAX
■ It stands for Asynchronous Javascript And XML
■ It's a technique for creating “better, faster, more
responsive web applications”
■ It’s not a new technology, but today it's more and more
used, especially by Google, Microsoft, etc.
■ How does it work?
JavaScript applications perform requests to the server
The server responds with the requested information
All this takes place without reloading the page and
without blocking the page (asynchronous of the
client)
Javascript then processes the result and manipulates
the page
XML is used for data exchange, even if you can also
use JSON or preformatted HTML, or simple text
Giacomo Fazio - 2011 47
47. AJAX
■ Nobody forces you to use JavaScript, since you can
also use concurrent technologies like VBScript, but
JavaScript is widely adopted, cross-browser and
cross-platform, so we will deal only with it
■ So AJAX is simply the idea of enabling your browser
to communicate asynchronously with the server to
provide a richer user “Web 2.0” experience.
■ It's faster because less data is transmitted and
because the browser has less work to do
■ It allows a better user experience and interaction with
the web page
■ Better solution than Java applets or Flash, because it
is cross-browser, cross-platform, lighter, no need to
install other plugins, no proprietary, etc.
Giacomo Fazio - 2011 48
48. AJAX
■ This is the model of an AJAX Web Application:
■ An intermediary layer (Ajax engine) is introduced between the
user and the server, written in JavaScript and usually in a hidden
frame
■ This engine is responsible for both rendering the interface and
communicating with the server on the user’s behalf.
Giacomo Fazio - 2011 49
49. AJAX
■ In particular every user action that normally would generate an
HTTP request takes the form of a JavaScript call to the Ajax
engine instead:
any response to a user action that doesn’t require a trip back to
the server (such as simple data validation, editing data in
memory, and even some navigation) is handled directly by the
engine
if the engine needs something from the server in order to
respond (if it’s submitting data for processing, loading
additional interface code, or retrieving new data) the engine
makes those requests asynchronously, usually using XML,
without interrupting the user’s interaction with the application.
■ Using AJAX in our example of the stocks trends, we can have in
our page, among the other things, a field in which we can view the
stocks trends, with a button that, if pressed, will do an AJAX call,
get the new trends from the server and show them in the field,
without reloading the whole page and without making us wait. We
can also avoid the button and do an automatic refresh every n
seconds.
Giacomo Fazio - 2011 50
50. JavaScript and AJAX
■ Your browser has to support the XMLHttpRequest (XHR) API, used to send
HTTP or HTTPS requests directly to a web server: new browsers surely
support it
■ All starts from JavaScript: if your browser doesn't support it, it won't support
AJAX
■ JavaScript has to create an XMLHttpRequest object, and send it (via
HTTP) to the server
■ Nothing special is required of the server (every server can handle HTTP
requests)
var request = null;
function getXMLHttpRequest( ) {
try {
request = new XMLHttpRequest();
}
catch(err1) {
request = null;
}
if (request == null) alert("Error creating request object!");
}
Giacomo Fazio - 2011 51
51. JavaScript and AJAX
function sendRequest() {
getXMLHttpRequest();
var url = some URL
request.open("GET", url, true); //or POST
request.onreadystatechange = handleTheResponse;
request.send(null); //or send(content), if POST
}
function handleTheResponse() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText;
// do something with the response string
} else {
alert("Error! Request status is " + request.status);
}
}
}
■ In the page:
<input value="Click Me" type="button" onclick="sendRequest">
Giacomo Fazio - 2011 52
52. jQuery and AJAX
■ It's not that simple to handle AJAX from JavaScript
■ The problem is solved by jQuery, that has many ways to work with
AJAX and allows the user to do it in a simple and efficient way
■ You don't have anymore to work directly with the XMLHttpRequest
object and with all the JavaScript functions
■ Consider a function that has to write a string on a file:
Input data:
JavaScript function format
function write_data() {
data as in
var data2send= { the example
'data' : $('#textarea').val()
};
$.post("http://localhost/write_file.php", data2send,
function(data){
if(data) alert("Data saved successfully!");
else alert("Error! Please retry!");
}); POST method to
} pass parameters: Output data
Giacomo Fazio - 2011 you can also use GET 53
53. jQuery and AJAX
■ File write_file.php on the server:
All the input data
<?php can be found
as fields of the
$data = $_REQUEST['data']; $_REQUEST array:
the data2send structure
file_put_contents('testfile' , $data); has become an
print true; associative array
?>
You have to print the
result of the function,
in order to return it to
the JavaScript function
Giacomo Fazio - 2011 54
54. jQuery and AJAX
■ It works, but this way you will create a different PHP file for each
AJAX call.
■ Let's make things in a more efficient and tidy way, by creating a file
on the server that contains many functions and by passing in
data2send the function to call.
■ The JavaScript function becomes:
function write_data() { function to execute
var data2send= {
'func': 'write_on_file', on server
'data' : $('#textarea').val()
};
$.post("http://localhost/procedures_retrieve.php", data2send,
function(data){
if(data) alert("Data saved successfully!");
else alert("Error! Please retry!");
});
}
Giacomo Fazio - 2011 55
55. jQuery and AJAX
■ File procedures_retrieve.php on the server:
<?php
$func = $_REQUEST['func'];
$res = $func($_REQUEST);
print $res;
function write_on_file($req) {
$data=$req['data'];
file_put_contents('testfile' , $data);
return true;
}
?>
Giacomo Fazio - 2011 56
56. jQuery and AJAX
■ Now it's ok, but we can make things even better
■ The JavaScript function becomes:
function write_data() {
var data2send= {
'func': 'write_on_file',
'data' : $('#textarea').val()
};
$.post("http://localhost/rpc.php", data2send,
function(data){
if(data) alert("Data saved successfully!");
else alert("Error! Please retry!");
});
}
Giacomo Fazio - 2011 57
57. jQuery and AJAX
■ File rpc.php on the server:
<?php
require_once 'procedures_retrieve.php';
$func = $_REQUEST['func'];
$res = $func($_REQUEST);
print $res;
?>
■ File procedures_retrieve.php on the server:
<?php
function write_on_file($req) {
$data=$req['data'];
file_put_contents('testfile' , $data);
return true;
}
?>
Giacomo Fazio - 2011 58
58. jQuery and AJAX
■ Our PHP function returns only 'true'. But if we have to
return objects?
■ Let's introduce the JSON encoding
■ The JavaScript function becomes:
function write_data() {
var data2send= {
'func': 'write_on_file',
'data' : $('#textarea').val()
};
$.post("http://localhost/rpc.php", data2send,
function(data){
if(data) alert(data); JSON encoding:
else alert("Error! Please retry!"); JavaScript expects
},'json'); an object encoded
in JSON
}
Giacomo Fazio - 2011 59
59. jQuery and AJAX
■ File rpc.php on the server:
JSON encoding:
<?php
require_once 'procedures_retrieve.php';
the jQuery function expects
$func = $_REQUEST['func']; something encoded in
if (function_exists($func)) { JSON, so it knows
header('Content-Type: text/plain; charset=utf-8');
print json_encode($func($_REQUEST)); how to handle it
}
else {
print json_encode(array (
'status' => '404',
'func' => $func
));
}
?>
■ File procedures_retrieve.php on the server:
<?php
function write_on_file($req) {
$data=$req['data'];
file_put_contents('testfile' , $data); I'm returning an object
return $req;
}
?>
Giacomo Fazio - 2011 60
60. What's JSON?
■ JSON stands for JavaScript Object Notation and is a
subset of JavaScript, in fact it can be parsed by a
JavaScript parser
■ It's simultaneously human- and machine-readable format
■ It has support for Unicode, allowing almost any information
in any human language to be communicated
■ It can represent either complex or simple data: Strings,
Number, Boolean, Objects, Arrays, Records, Lists, Trees
■ E.g. of Object:
{ "name": "Jack Nimble", "format": { "type": "rect", "width":
120, "interlace": false}}
■ E.g. of Array:
["Sunday", "Monday", "Tuesday", "Wednesday“]
■ Also compatible with other languages like C, C++, C#,
ColdFusion, Python and many more.
Giacomo Fazio - 2011 61
61. jQuery and AJAX
■ One more thing: in a PHP function called by AJAX, everything written
to STDOUT/STDERR won't be shown, instead will be written in a
buffer and all its content is the return value of the function when it
finishes
■ So don't use functions like echo(), print_r or var_dump(), they are
useless and they would ruin your output by adding things you don't
want.
■ Instead write to a file your temporary output, by using
$res=print_r($object,true); //saves the output on $res
file_put_contents(”filename”,$res);
■ For the same reason, disable errors showing through
ini_set('display_errors', 0); at the beginning of the file rpc.php,
instead enable option ”log_errors” in php.ini and select a writeable
file, then always look at that file, you will find there your errors
■ So add this at the beginning of your rpc.php:
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors',TRUE);
ini_set('error_log','errorlog');
Giacomo Fazio - 2011 62
62. How to debug?
■ The easy way:
print_r and var_dump() for PHP (include it in the HTML tag <pre></pre>
to avoid seeing the results only in one line);
alert() or console.log() for JavaScript / jQuery
When you want to see the structure of an object in Javascript / jQuery (for
example the object returned from a AJAX call) you can use this function:
function print_r(theObj){
if(theObj.constructor == Array || theObj.constructor == Object){
document.write("<ul>");
for(var p in theObj){
if(theObj[p].constructor == Array || theObj[p].constructor ==
Object){
document.write("<li>["+p+"] => "+typeof(theObj)+"</li>");
document.write("<ul>");
print_r(theObj[p]);
document.write("</ul>");
}
else document.write("<li>["+p+"] => "+theObj[p]+"</li>");
}
document.write("</ul>");
}
}
Giacomo Fazio - 2011 63
63. How to debug?
As said before, during an AJAX call, on the server side you can't use
print_r() or var_dump(), so write to a file
The best way:
Use Firebug/Chrome Developer Tools, really useful for
JavaScript/jQuery and to control request and response of AJAX calls
(you will find many tutorials in Internet)
As said before, enable option ”log_errors” in php.ini and select a
writeable file, then always look at that file, especially for AJAX calls
Use a PHP debugger that includes also tracing and profiling
features, such as XDebug (you have at first to install and enable it in
your php.ini)
Use an IDE (ex. NetBeans or Aptana Studio), that can control
XDebug in a graphical and easy way
Use Unit Testing: I suggest to use PHPUnit to test PHP code (look
here and then here) and QUnit to test JavaScript/jQuery code (look
here and here)
A look to the TestSwarm website could be interesting as well.
Probably the best solution is to combine all the techniques!
Giacomo Fazio - 2011 64
64. AJAX limitations
■ For further information about jQuery and AJAX
you can find a lot of stuff on the Internet, for
example here
■ AJAX is a great technology, but it has some
limitations:
Back functionality doesn't work because the
dynamic pages don’t register themselves to
the browsers history engine (this can be
solved using Iframes and/or anchor tags, as
showed here and here)
The page cannot be bookmarked if
implemented using AJAX
Giacomo Fazio - 2011 65
65. AJAX limitations
Returning to our example of the stocks trends, we
solved a lot of problems using AJAX but, in order to
view updated stocks trends in the field, we have to use
polling, that is we have to do a call to the server every
n seconds, with the drawback to waste server
resources and bandwidth. If the millions of users of a
large site do this every few seconds, the effect on the
server would be similar to a DOS attack! The solution
could be not to use polling and make the server gives
data to the browser as soon as data on the server
have changed. This is not possible, since in AJAX all
the server processing is done at the request of the
client, the server can only answer and can't start a
communication towards the client...
Giacomo Fazio - 2011 66
66. AJAX: polling example (client side)
For example, with the polling approach, this could be the
function called by jQuery to retrieve the number of users
currently registered:
function retrieve_numusers() {
var data2send= {
'func': 'retrieve_numusers',
};
$.post("http://localhost/example2/rpc.php", data2send, function(data){
if(!data) alert("Error! Please retry!");
else {
$('#numusers').text(data); //writes the number in the document
setTimeout('retrieve_numusers()',10000);
}
},'json');
}
$(document).ready(function(){
retrieve_numusers();
});
So we are calling the function every 10 sec.
Giacomo Fazio - 2011 67
67. AJAX: polling example (server side)
And this, assuming that updated data are on a
database, could be the function on the server:
function retrieve_numusers($req) {
$conn=mysql_connect("localhost","root","") or die ("<br />Error
in the database connection " . mysql_error($conn));
mysql_select_db("example", $conn);
$query="SELECT surname FROM user";
$res=mysql_query($query);
$num=mysql_num_rows($res);
return $num;
}
So this is the situation:
Waste of resources
Waste of bandwidth
The solution is... Comet!
Giacomo Fazio - 2011 68
68. Comet: overview
Comet is a web application model
which allows a web server to push
data to a browser, without the
browser explicitly requesting it
Called also Ajax Push, Ajax Reverse,
HTTP Push, etc.
Two types of Comet techniques: long
polling and streaming (Hidden
IFrame and Multipart
XMLHttpRequest)
Giacomo Fazio - 2011 69
69. Comet: long polling
It is very similar to polling, except the request sleeps
on the server and if at any time data becomes
available, the server immediately returns the
requested data to the client.
So this represents the situation:
Giacomo Fazio - 2011 70
70. Comet: long polling example (client side)
For example, with the long polling approach, this could be the function called
by jQuery to retrieve the number of users currently registered:
function retrieve_numusers() {
var data2send= {
'func': 'retrieve_numusers'
};
if($('#numusers').text()!="") data2send.currentnum=$('#numusers').text();
$.post("http://localhost/example3/rpc.php", data2send, function(data){
if(!data) alert("Error! Please retry!");
else {
$('#numusers').text(data); //writes the number in the document
retrieve_numusers();
}
},'json');
}
$(document).ready(function() {
retrieve_numusers();
});
We are doing the AJAX call passing to the server function the previous
value, in order to see if it has changed or not.
If the server function returns (because the value changed or because of
timeout), the client will do the call again without waiting
Giacomo Fazio - 2011 71
71. Comet: long polling example (server side)
And this could be the function on the server:
set_time_limit(0); //to avoid timeouts
function retrieve_numusers($req) {
while(true) {
$conn=mysql_connect("localhost","root","") or die ("<br />Error in the
database connection " . mysql_error($conn));
mysql_select_db("example", $conn);
$query="SELECT surname FROM user";
$res=mysql_query($query);
$num=mysql_num_rows($res);
if(!isset($req["currentnum"]) || $num!=$req["currentnum"]) return $num;
}
}
We passed to the function $req["currentnum"], so the server
can understand if the value taken from the database has
changed
The function returns only if $req["currentnum"] is not set (that is
it is the first time we call the function) or if the value has
changed
Giacomo Fazio - 2011 72
72. Comet: long polling
One factor you must keep in mind is that, if you
can't avoid timeouts like we did with
set_time_limit(0), your AJAX request can time out
if you sleep too long. To overcome timing out, you
should only sleep for less than the timeout, then
return, and the client must repeat the long poll
request until data becomes available.
Long polling drawback: the two-connection per
host name limit for some browsers, that is you
cannot open two connections to the same host
name with long-lived connections and open a third
connection to same server; this is due to security
restrictions of some web browsers.
Giacomo Fazio - 2011 73
73. Comet: Hidden IFrame
It is also referred as the ”Forever
Frame” technique
IFrame stands for Inline Frame. It
is part of HTML and it allows a
Web page to embed one HTML
document inside another HTML
element.
It doesn't use AJAX
Giacomo Fazio - 2011 74
74. Comet: Hidden IFrame
With the Hidden IFrame approach, you have at first to create an iframe
element in your document, setting the height and the frameborder to 0 (in
order to make it hidden):
<iframe name="hidden_iframe" id="hidden_iframe" frameborder="0"
height="0" width="0" src="server.php"></iframe>
As you can see, the iframe content is the file server.php whose example
code below shows it never returns completely from the call, but every
time, after a certain elaboration, it injects a JavaScript code into the
iframe, passing it the updated result of the elaboration:
while(true) {
$num=rand(); //it generates a random number
echo "<br /><br />"; //it may be necessary to send some noise to make it work
echo "<script type='text/javascript'>alert($num);</script>";
sleep(1); //a little break for the server
}
With AJAX, the server function had to end after having sent a value
and then it could be called again
With the Hidden Iframe approach it's not necessary: the function
can send a value to the client and continue executing
Giacomo Fazio - 2011 75
75. Comet: Hidden IFrame
We can improve this model by using the usual approach (rpc.php and
procedures_retrieve.php), especially if we are already using it with AJAX
on our website and we want a tidy solution without many files. So we
could use GET in the iframe content to choose the function :
<iframe name="hidden_iframe" id="hidden_iframe" frameborder="0" height="0"
width="0" src="rpc.php?func=function1"></iframe>
We can also specify
rpc.php is the usual
other parameters
<?php using GET
require_once 'procedures_retrieve.php'; or use JSON
$func = $_REQUEST['func']; to send objects
if (function_exists($func)) {
header('Content-Type: text/plain; charset=utf-8');
print json_encode($func($_REQUEST));
}
else {
print json_encode(array ( Values in GET are in
'status' => '404', $_REQUEST and are
'func' => $func passed to the function
));
}
?>
Giacomo Fazio - 2011 76
76. Comet: Hidden IFrame
■ In procedures_retrieve.php, among the other
functions, we have:
function function1($req) {
set_time_limit(0); //no timeouts
ob_implicit_flush(); //explicit calls to flush() will no longer be needed
$num=rand(); //it generates a random number
echo "<br /><br />"; //it may be necessary to send some noise
echo "<script type='text/javascript'>alert($num);</script>";
sleep(1); //a little break for the server
}
■ The line print json_encode($func($_REQUEST)) in
rpc.php won't print anything, but we leave it in that it
could be needed for other server functions (for
example for AJAX)
Giacomo Fazio - 2011 77
77. Comet: Hidden IFrame example
So we will use this approach in our example of the registered users.
We use this iframe on the client:
<iframe name="hidden_iframe" id="hidden_iframe" frameborder="0" height="0"
width="0" src="rpc.php?func=retrieve_numusers"></iframe>
rpc.php is the usual. This is our function in procedures_retrieve.php:
function retrieve_numusers($req) {
set_time_limit(0); //no timeouts
ob_implicit_flush(); //explicit calls to flush() will no longer be needed
$old_num=-1;
while(true) {
$conn=mysql_connect("localhost","root","");
mysql_select_db("example", $conn);
$query="SELECT surname FROM user";
$res=mysql_query($query);
$num=mysql_num_rows($res);
if($num!=$old_num) {
echo "<br /><br />"; //it may be necessary to send some noise
echo "<script type='text/javascript'>parent.update_numusers($num);</script>";
$old_num=$num;
}
sleep(1); //a little break for the server
}
}
Giacomo Fazio - 2011 78
78. Comet: Hidden IFrame example
■ It never returns completely from the call, but every
time it injects a JavaScript code into the iframe,
passing it the updated number of registered users
■ What does that line do? It will call the client function
update_numusers(), whose purpose is to write in the
document the updated number
function update_numusers(num) {
$('#numusers').text(num);
}
■ Since the server function doesn't terminate after
having sent a value to the client, it can handle the old
value and there is no need to get it from the client
anymore
Giacomo Fazio - 2011 79
79. Comet: Hidden IFrame drawbacks
■ Drawbacks of the Hidden IFrame approach:
IFrames were never meant to serve as a
control for handling streaming. As such, this
approach has been criticized by some as
being a bit of a "hack".
IFrames are slow-loading elements, if
compared to the alternatives
It causes browsers to leave the loading bar
visible indefinitely, and in some browsers
continually shows a wait cursor
Lack of a reliable error handling method
Impossibility of tracking the state of the
request calling process
Giacomo Fazio - 2011 80
80. Comet: Multipart XMLHttpRequest
Multipart XMLHttpRequest (MXHR) is a feature invented in
1995 by Netscape Navigator, which allowed servers to send
new versions of an image or HTML page to the browser, as
part of a multipart HTTP response, using the content type
multipart/x-mixed-replace.
Since 2004, Gecko-based browsers such as Firefox accept
multipart responses to XHR, which can therefore be used as
a streaming Comet transport
On the server side, each message is encoded as a separate
portion of the multipart response
On the client side, the callback function provided to the XHR
onreadystatechange() function will be called as each
message arrives.
This functionality is only included in Gecko-based browsers;
there was a discussion about adding it to WebKit (Chrome,
Safari, etc.) but with the coming of HTML5 it was set aside
Giacomo Fazio - 2011 81
81. Comet drawbacks
HTTP request and response headers, which
contain lots of additional, unnecessary header
data and introduce latency.
Effort to simulate full-duplex communication
over half-duplex HTTP
Significant overhead in terms of resource
consumption
Lots of complexity
Error-prone
Reduction of CPU performance
HTTP wasn't designed for real-time, full-duplex
communication!
Future solution: HTML5 WebSockets!
Giacomo Fazio - 2011 82
82. The future: HTML5
HTML5 is a markup language for the projectation of webpages.
Still draft: W3C says it will be ready for July 2014.
The initial specifics have been created by an external group from W3C,
called WHATWG.
Now both WHATWG and W3C HTML are following it.
Main objectives:
The main aim was to propose new commands and features that were
so far obtained in a non-standard way, that is through plugins or
proprietary extensions, which sometimes worked only for some
browsers.
Guarantee compatibility with browsers, including the mobile ones.
Separate content from presentation (use CSS)
Support for geolocation
New tags <audio> and <video> to handle media
Support for the Canvas element that allows to create animations and
vectorial graphics through JavaScript
Support for offline web applications
Drag and drop
WebSockets
And many others...
Giacomo Fazio - 2011 83
83. HTML5: WebSockets
We are particularly interested in WebSockets
HTTP:
half-duplex (traffic flows in only one direction at a time)
Hard to achieve real-time, bi-directional communication, even with
Comet
Tons of unnecessary HTTP header information sent with each HTTP
request and response and added latency, with overhead as much as
2 Kbytes
WebSocket:
New protocol that uses the same TCP connection
Bi-directional, full-duplex, text based socket
The web application client can maintain an always open connection
with the server and data can be sent and received at the same time:
no need to use anymore polling or Comet techniques
Enables webpages to communicate with a remote host
Traverses firewalls, proxies and routers seamlessly
Dramatic overhead reduction (2 bytes overhead per frame)
Reduced complexity
It is still a draft, but it will be the future, and now it has reached
enough stability to be discussed
Giacomo Fazio - 2011 84
84. HTML5: WebSockets performance
Suppose you have a web application which uses the polling approach
and whose overhead for request and response headers is 871 bytes (not
so bad, considering that it can reach 2 Kbytes)
With WebSockets overhead is only 2 bytes
What happens when many users use this application?
Use case A: 1000 clients
With polling network throughput is 871*1000 = 871000 bytes =
6968000 bits per second (6.6 Mbps)
With WebSockets network throughput is 2*1000 = 2000 bytes =
16000 bits per second (0.015 Mbps)
Use case B: 10000 clients
With polling network throughput is 871*10000 = 8710000 bytes =
69680000 bits per second (66 Mbps)
With WebSockets network throughput is 2*10000 = 20000 bytes =
160000 bits per second (0.153 Mbps)
Use case C: 100000 clients:
With polling network throughput is 871*100000 = 87100000 bytes =
696800000 bits per second (665 Mbps)
With WebSockets network throughput is 2*100000 = 200000 bytes =
1600000 bits per second (1.526 Mbps)
Giacomo Fazio - 2011 85
86. HTML5: WebSockets (client side)
In order to use AJAX we had to use the XmlHttpRequest API,
for WebSockets new APIs have been defined.
Now all the browsers support XmlHttpRequest (so they can
use AJAX), but for WebSockets we have to use a browser
which supports them:
currently they are supported and enabled in new versions
of Chrome and Safari.
supported, but you have to enable them, on new versions
of Firefox and Opera
The client side code can be written in JavaScript / jQuery.
The main thing is the object WebSocket, we have to give it
a URL on the server when we build it
We’ll be using three events:
onopen: When a socket has opened
onmessage: When a message has been received
onclose: When a socket has been closed
Giacomo Fazio - 2011 87
88. HTML5: WebSockets (server side)
On server side, for AJAX we had to do nothing, because
nothing changed for servers
The situation for WebSockets is more complicated, since we
are not using HTTP, but a new protocol.
We must have a server listening to eventual connection
requests from the client
Soon webservers and/or server-side languages will support
completely WebSockets, but right now there are only
unstable or beta solutions to implement them: new
webservers only for them, Apache extensions, etc.
Examples: phpwebsocket, jWebSocket, web-socket-ruby,
mod-pywebsocket, which allow the user to create a
WebSocket on the server accepting connections from the
client and to define what is the behavior to adopt when a
message from the client arrives (you have to code
respectively in PHP, Java, Ruby on Rails, Python).
Giacomo Fazio - 2011 89
89. HTML5: WebSockets (server side)
I decided to use phpwebsocket, since I want to code in PHP
and, moreover, I have already the functions to execute server-
side in PHP and I want to reuse them
You can find phpwebsocket here
Use the class version, contained in websocket.class.php, you
have to create a new class that extends it and overrides the
method process() in order to do what you like
Then you have to create a php file that creates a new object
from this class, specifying server and port, and launch it with
php q filename.php
Now you have a WebSocket on your server, listening on the
port that you chose
There's a bug in the current version with the first message sent
to the browser. Solution:
change line 102 in websocket.class.php to
socket_write($user->socket,$upgrade.chr(0).chr(255),strlen($upgrade)+2);
send something like ”rr” as first message
if it doesn't work properly, simply relaunch the server
Giacomo Fazio - 2011 90
90. HTML5: WebSockets (object passing)
With AJAX we passed data as a particular structure with the
form { 'name': 'value', 'name2': 'value2' } which in the server
function became an associative array ($_REQUEST)
Then we returned an object encoded in JSON through the
function json_encode and the jQuery function which received it
automatically did the conversion, since we had indicated it to
expect JSON as result
Here the WebSockets exchange messages as strings
So we can always send objects, but we have to handle JSON
encoding manually:
We can encode an object from JavaScript / jQuery with
JSON.stringify(objectname)
We can decode it in PHP with json_decode($msg,true),
that obtains an associative array
Encode the object to return from PHP as usual, with
json_encode
Decode it in JavaScript/jQuery with JSON.parse(msg.data)
Giacomo Fazio - 2011 91
91. WebSockets instead of AJAX (client side)
WebSockets can be used for many things, but in this document we are
interested in using them to substitute AJAX and in particular Comet
For example, the following could be the client side part to call a server
function
var ws;
function call_server_function() {
var data2send= {
'func': 'server_function'
};
ws.send(JSON.stringify(data2send));
}
$(document).ready(function(){
ws = new WebSocket("ws://localhost:12345");
ws.onopen = function () {
ws.send("rr"); //to avoid the first message bug
call_server_function();
};
We are using JSON
ws.onmessage = function(msg) {
alert(JSON.parse(msg.data)); because we will
}; receive a JSON string
ws.onclose = function () { from the server
};
});
Giacomo Fazio - 2011 92
92. WebSockets instead of AJAX (server side)
On the server side, we have to extend the WebSocket class and override the
method ”process()”.
In particular we will make it have the same behavior of our old rpc.php, which calls
the functions in procedures_retrieve.php (that in fact is included)
include "websocket.class.php";
require_once ”procedures_retrieve.php”;
class MyWebSocketServer extends WebSocket{
function process($user,$msg) {
$this->say("< ".$msg); //enable only to see what arrives to the server
$msg_dec=json_decode($msg,true);
if(is_array($msg_dec)) {
$func = $msg_dec['func']; This is the code of
if (function_exists($func)) { mywebsocketserver.php.
$res=json_encode($func($msg_dec)); We can launch it with
} php q mywebsocketserver.php
else {
$res=json_encode(array (
'status' => '404',
'func' => $func
));
}
Creation of the
$this->send($user->socket,$res); WebSocket
}
}
on the server
}
$master = new MyWebSocketServer("localhost",12345);
Giacomo Fazio - 2011 93
93. WebSockets instead of AJAX (server side)
Then on procedures_retrieve.php there
must be the function server_function() that
the client wants to call and which will
return something:
function server_function($req) {
…
return $msg;
}
Giacomo Fazio - 2011 94
94. WebSockets example (client side)
With the WebSockets approach we can handle our example of
retrieving the number of users currently registered, without the
drawbacks of the long polling approach. This is the client side code:
var ws;
function retrieve_numusers() {
var data2send= {
'func': 'retrieve_numusers'
};
ws.send(JSON.stringify(data2send));
}
$(document).ready(function(){
ws = new WebSocket("ws://localhost:12345");
ws.onopen = function () {
ws.send("rr"); //to avoid the first message bug
retrieve_numusers();
};
ws.onmessage = function(msg) {
if(!isFinite(msg.data)) alert("Error! Please retry!");
else $('#numusers').text(JSON.parse(msg.data));
};
ws.onclose = function () {
};
});
Giacomo Fazio - 2011 95
95. WebSockets example (client side)
Maybe you expected some behaviors similar to the
long polling case, but they are not necessary
anymore:
We call retrieve_numusers() only in the
onopen() function, since the function executed
server side doesn't need anymore to finish after
having returned a value (unlike in AJAX and
Comet), so it will execute forever and there is
no need to care about a recall
We don't pass the previous value anymore
when we call the server: since the server side
function doesn't end after having sent a value,
it can keep the last number got from the
database and see if changes occur, without the
need to get that value from the client
Giacomo Fazio - 2011 96
96. WebSockets example (server side)
On the server side, when calling the function present in procedures_retrieve.php, we
have to pass it also the current object and the variable $user, because transmission
has to be done within the function, we will see why later
include "websocket.class.php";
require_once ”procedures_retrieve.php”;
class MyWebSocketServer extends WebSocket{
function process($user,$msg) {
$this->say("< ".$msg); //enable only to see what arrives to the server
$msg_dec=json_decode($msg,true); We are passing also the
if(is_array($msg_dec)) {
$func = $msg_dec['func']; current object and the
if (function_exists($func)) { variable $user
$res=json_encode($func($msg_dec,$this,$user));
}
else {
$res=json_encode(array (
'status' => '404',
'func' => $func
));
} Creation of the
$this->send($user->socket,$res); WebSocket
}
} on the server
}
$master = new MyWebSocketServer("localhost",12345);
Giacomo Fazio - 2011 97
97. WebSockets example (server side)
In AJAX and in Comet the server function had to end
after having sent a value, now it's not necessary
anymore: the function can send a message with the
new value and continue executing
So it will handle the old value and there is no need to
get it from the client anymore
Anyway, we have to send the message from within the
function, that's why we have as input parameters also
the websocket server and the variable $user
So in this case the line $this->send($user->socket,
$res) in mywebsocketserver.php is not necessary, but
we leave it in that it could be needed for other server
functions
This is the function retrieve_numusers():
Giacomo Fazio - 2011 98
98. WebSockets example (server side)
function retrieve_numusers($req,$wsserver,$user) {
set_time_limit(0); //no timeouts
$old_num=-1;
while(true) { //the function never ends
$conn=mysql_connect("localhost","root","") or die
("<br />Error in the database connection " .
mysql_error($conn));
mysql_select_db("example", $conn);
$query="SELECT surname FROM user";
$res=mysql_query($query);
$num=mysql_num_rows($res);
if($num!=$old_num) {
$res=json_encode($num);
$wsserver->send($user->socket,$res);
$old_num=$num;
}
}
}
Giacomo Fazio - 2011 99
99. HTML5: Server-Sent Events (SSE)
WebSockets provide a richer protocol to perform
bi-directional, full-duplex communication, useful for
things like games, messaging apps and for cases
where you need near real-time updates in both
directions.
However, in some scenarios data doesn't need to
be sent from the client, you simply need updates
from some server action (for example friends'
status updates, stock tickers, news feeds)
Server-Sent Events (SSE) is another possible
alternative which comes from HTML5
The original API was created by Opera in 2006 and
is used for pushing events from the server to the
client.
Giacomo Fazio - 2011 100
100. HTML5: Server-Sent Events (SSE)
The client cannot send messages to the server, it
can only listen for messages.
Like for WebSockets, the SSE approach opens a
persistent connection to the server, which sends data
to the client when new information is available,
eliminating the need for polling or Comet techniques
and their overhead
SSEs are sent over traditional HTTP. So no need for a
special protocol or server implementation
Moreover they have been designed to be efficient
SSE have a variety of features that WebSockets lack
by design such as automatic reconnection, event IDs,
and the ability to send arbitrary events.
So they could be a good tradeoff between
AJAX/Comet and the WebSockets
Giacomo Fazio - 2011 101
101. HTML5: SSE (client side)
As for WebSockets, new APIs have been defined for
SSE
We have to use a browser which supports them:
currently they are supported and enabled in new
versions of Chrome, Opera and Safari.
they will be surely supported in the future by Firefox
The client side code can be written in JavaScript /
jQuery.
The main thing is the object EventSource, we have
to give it a URL on the server when we build it
As for WebSockets, we’ll be using three events:
onopen: When the connection has been created
onmessage: When a message has been received
onclose: When the connection has been closed
Giacomo Fazio - 2011 102
102. HTML5: SSE (client side)
Example:
$(document).ready(function() {
var source = new EventSource('http://localhost/server.php');
source.onmessage = function (event) {
alert(event.data);
};
source.onopen = function (event) {
alert("Connected...");
};
source.onerror = function (event) {
alert("Error!");
};
});
Giacomo Fazio - 2011 103
103. HTML5: SSE (server side)
On server side (file server.php) nothing changes, since we
use the normal HTTP protocol
If the server has to give the client a response, this must
contain a "data:" line, followed by the message, followed by
two "n" characters:
header("Content-Type: text/event-stream");
header('Cache-Control: no-cache');
set_time_limit(0); //no timeouts
ob_implicit_flush(); //to avoid explicit calls to flush()
echo "data: Hello!nn"; //message from the server
Giacomo Fazio - 2011 104
104. SSE instead of AJAX (client side)
SSE can be used for many things, but in this document we are interested
in using them to substitute AJAX and in particular Comet
We would like to use the usual approach (rpc.php and
procedures_retrieve.php), because for example we are using it with
AJAX and Comet on our website and we want a tidy solution without
many files.
But how can we do, since with SSE client can't send messages to the
server and so it can't specify the function to execute? Actually it can,
when the object EventSource is created, by using GET
We can also specify other parameters when using GET and we can use
JSON to send objects
$(document).ready(function() {
var url='http://localhost/example_eventsource/rpc.php ?func=function1';
var source = new EventSource(url);
source.onmessage = function (event) {
alert(JSON.parse(event.data));
};
});
Giacomo Fazio - 2011 105
105. SSE instead of AJAX (server side)
The file rpc.php is a bit modified, since it must take the message from
the server and send it after having formatted it in the correct way
require_once 'procedures_retrieve.php';
$func = $_REQUEST['func'];
if (function_exists($func)) {
header('Content-Type: text/plain; charset=utf-8');
$ret=json_encode($func($_REQUEST));
}
else { Values in GET are in
$ret=json_encode(array ( $_REQUEST and are
'status' => '404', passed to the function
'func' => $func
));
}
print "data: $retnn";
On procedures_retrieve.php there must be function1(), for example:
function function1($req) {
header("Content-Type: text/event-stream");
header('Cache-Control: no-cache');
set_time_limit(0); //no timeouts
ob_implicit_flush(); //to avoid explicit calls to flush()
return "Hello!"; //message from the server
}
Giacomo Fazio - 2011 106
106. HTML5: SSE example (client side)
With the SSE approach we can handle our example of retrieving the
number of users currently registered, without the drawbacks of the
long polling approach. This is the client side code:
$(document).ready(function() {
var url='http://localhost/example_eventsource/rpc.php?func=retrieve_numusers';
var source = new EventSource(url);
source.onmessage = function (event) {
$('#numusers').text(JSON.parse(event.data));
};
});
As for WebSockets, we call the server function retrieve_numusers()
only once, since it doesn't need anymore to finish after having
returned a value, so it will execute forever and there is no need to
care about a recall
We don't pass the previous value anymore when we call the server:
since the server side function doesn't end after having sent a value, it
can keep the last number got from the database and see if changes
occur, without the need to get that value from the client
Giacomo Fazio - 2011 107
107. HTML5: SSE example (server side)
We are in a particular case: since the server function will execute
forever, it will never use the JSON encoding and return part of rpc.php,
so it makes no sense to use a different rpc.php, we can use the usual
rpc.php that we already use for AJAX functions:
require_once 'procedures_retrieve.php';
$func = $_REQUEST['func'];
if (function_exists($func)) {
header('Content-Type: text/plain; charset=utf-8');
print json_encode($func($_REQUEST));
} not used
else {
print json_encode(array (
'status' => '404',
'func' => $func
));
}
Giacomo Fazio - 2011 108
108. HTML5: SSE example (server side)
This is our function in procedures_retrieve.php:
function retrieve_numusers($req) {
header("Content-Type: text/event-stream");
header('Cache-Control: no-cache');
set_time_limit(0); //no timeouts
ob_implicit_flush(); //explicit calls to flush() will no longer be needed
$old_num=-1;
while(true) {
$conn=mysql_connect("localhost","root","");
mysql_select_db("example", $conn);
$query="SELECT surname FROM user";
$res=mysql_query($query);
$num=mysql_num_rows($res);
if($num!=$old_num) {
$msg=json_encode($num);
echo "data: $msgnn";
$old_num=$num;
}
}
}
■ As for WebSockets, the function will run forever, it can send a message with
the new value and continue executing
■ So it will handle the old value and there is no need to get it from the client
Giacomo Fazio - 2011 109
109. Aptana Studio
■ Aptana is an IDE (Integrated Development Environment). It can be
used to create websites and Web applications.
■ It's released under the GNU open source license: it can be
downloaded and used free of charge.
■ Aptana can be used to create simple websites or complex web
applications. It has got a quality and a quantity of features that allow it
to be a valid alternative to commercial softwares like Dreamweaver.
■ It's based on Eclipse and PDT (PHP Development Tools).
■ It can be downloaded as a standalone tool or as a plugin for Eclipse
■ It's cross-platform
■ You can find a good guide (in Italian) on
http://editor.html.it/guide/leggi/193/guida-aptana/
■ Other tutorials are present on the Aptana website,
http://docs.aptana.com/docs/index.php/Aptana_Tutorials
Giacomo Fazio - 2011 110