How to implement COMET with PHP
来源:互联网 发布:太阳能电池模拟软件 编辑:程序博客网 时间:2024/05/21 06:18
原始链接:http://www.zeitoun.net/articles/comet_and_php/start
How to implement COMET with PHP
Comet is a programming technique that enables web servers to send data to the client without having any need for the client to request it. This technique will produce more responsive applications than classic AJAX. In classic AJAX applications, web browser (client) cannot be notified in real time that the server data model has changed. The user must create a request (for example by clicking on a link) or a periodic AJAX request must happen in order to get new data fro the server.
I will now explain how to implement Comet with PHP programming language. I will demonstrate it on two demos which uses two techniques: the first one is based on hidden "<iframe>" and the second one is based on classic AJAX non-returning request. The first demo will simply show the server date in real time on the clients and the second demo will display a mini-chat.
Comet with iframe technique : server timestamp demo
We need:
- A PHP script that will handle the persistent http request (backend.php)
- A HTML file that will load Javascript code and that will show the data coming from the server (index.html)
- The prototype library that will help us to write simple JS code
To understand how it works this schema should help:
The backend script (PHP)
This script will do an infinite loop and will return the server time as long as the client is connected. Call it "backend.php":
<?php header("Cache-Control: no-cache, must-revalidate"); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); flush(); ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Comet php backend</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <script type="text/javascript"> // KHTML browser don't share javascripts between iframes var is_khtml = navigator.appName.match("Konqueror") || navigator.appVersion.match("KHTML"); if (is_khtml) { var prototypejs = document.createElement('script'); prototypejs.setAttribute('type','text/javascript'); prototypejs.setAttribute('src','prototype.js'); var head = document.getElementsByTagName('head'); head[0].appendChild(prototypejs); } // load the comet object var comet = window.parent.comet; </script> <?php while(1) { echo '<script type="text/javascript">'; echo 'comet.printServerTime('.time().');'; echo '</script>'; flush(); // used to send the echoed data to the client sleep(1); // a little break to unload the server CPU } ?> </body> </html>
The client script (HTML)
This HTML document first load the prototype library in the "<head>" tag, then it create the tag that will contains the server timer "<div id="content"></div>", and finally it create a "comet" javascript object that will connect the backend script to the time container tag.
The comet object will create some invisible "iframe" tags (depends on the web browser). These iframes are in charge to create the background persistent http connection with the backend script. Notice: this script do not handle possible connection problems between client and server.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Comet demo</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="prototype.js"></script> </head> <body> <div id="content">The server time will be shown here</div> <script type="text/javascript"> var comet = { connection : false, iframediv : false, initialize: function() { if (navigator.appVersion.indexOf("MSIE") != -1) { // For IE browsers comet.connection = new ActiveXObject("htmlfile"); comet.connection.open(); comet.connection.write("<html>"); comet.connection.write("<script>document.domain = '"+document.domain+"'"); comet.connection.write("</html>"); comet.connection.close(); comet.iframediv = comet.connection.createElement("div"); comet.connection.appendChild(comet.iframediv); comet.connection.parentWindow.comet = comet; comet.iframediv.innerHTML = "<iframe id='comet_iframe' src='./backend.php'></iframe>"; } else if (navigator.appVersion.indexOf("KHTML") != -1) { // for KHTML browsers comet.connection = document.createElement('iframe'); comet.connection.setAttribute('id', 'comet_iframe'); comet.connection.setAttribute('src', './backend.php'); with (comet.connection.style) { position = "absolute"; left = top = "-100px"; height = width = "1px"; visibility = "hidden"; } document.body.appendChild(comet.connection); } else { // For other browser (Firefox...) comet.connection = document.createElement('iframe'); comet.connection.setAttribute('id', 'comet_iframe'); with (comet.connection.style) { left = top = "-100px"; height = width = "1px"; visibility = "hidden"; display = 'none'; } comet.iframediv = document.createElement('iframe'); comet.iframediv.setAttribute('src', './backend.php'); comet.connection.appendChild(comet.iframediv); document.body.appendChild(comet.connection); } }, // this function will be called from backend.php printServerTime: function (time) { $('content').innerHTML = time; }, onUnload: function() { if (comet.connection) { comet.connection = false; // release the iframe to prevent problems with IE when reloading the page } } } Event.observe(window, "load", comet.initialize); Event.observe(window, "unload", comet.onUnload); </script> </body> </html>
Download it
Here is the tar.gz archive of this demo.
Comet with classic AJAX : litte chat demo
As on the above technique, we need:
- A file to exchange data (data.txt)
- A PHP script that will handle the persistent http request (backend.php)
- A HTML file that will load Javascript code and that will show the data coming from the server (index.html)
- The prototype library that will help us to write simple JS code
The backend script (PHP)
This script will do two things:
- Write into "data.txt" when new messages are sent
- Do an infinite loop as long as "data.txt" file is unchanged
<?php $filename = dirname(__FILE__).'/data.txt'; // store new message in the file $msg = isset($_GET['msg']) ? $_GET['msg'] : ''; if ($msg != '') { file_put_contents($filename,$msg); die(); } // infinite loop until the data file is not modified $lastmodif = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0; $currentmodif = filemtime($filename); while ($currentmodif <= $lastmodif) // check if the data file has been modified { usleep(10000); // sleep 10ms to unload the CPU clearstatcache(); $currentmodif = filemtime($filename); } // return a json array $response = array(); $response['msg'] = file_get_contents($filename); $response['timestamp'] = $currentmodif; echo json_encode($response); flush(); ?>
The client script (HTML)
This HTML document first load the prototype library in the "<head>" tag, then it create the tag "<div id="content"></div>" that will contains the chat messages comming from "data.txt" file, and finally it create a "comet" javascript object that will call the backend script in order to watch for new chat messages.
The comet object will send AJAX requests each time a new message has been received and each time a new message is posted. The persistent connection is only used to watch for new messages. A timestamp url parameter is used to identify the last requested message, so that the server will return only when the "data.txt" timestamp is newer that the client timestamp.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Comet demo</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="prototype.js"></script> </head> <body> <div id="content"> </div> <p> <form action="" method="get" onsubmit="comet.doRequest($('word').value);$('word').value='';return false;"> <input type="text" name="word" id="word" value="" /> <input type="submit" name="submit" value="Send" /> </form> </p> <script type="text/javascript"> var Comet = Class.create(); Comet.prototype = { timestamp: 0, url: './backend.php', noerror: true, initialize: function() { }, connect: function() { this.ajax = new Ajax.Request(this.url, { method: 'get', parameters: { 'timestamp' : this.timestamp }, onSuccess: function(transport) { // handle the server response var response = transport.responseText.evalJSON(); this.comet.timestamp = response['timestamp']; this.comet.handleResponse(response); this.comet.noerror = true; }, onComplete: function(transport) { // send a new ajax request when this request is finished if (!this.comet.noerror) // if a connection problem occurs, try to reconnect each 5 seconds setTimeout(function(){ comet.connect() }, 5000); else this.comet.connect(); this.comet.noerror = false; } }); this.ajax.comet = this; }, disconnect: function() { }, handleResponse: function(response) { $('content').innerHTML += '<div>' + response['msg'] + '</div>'; }, doRequest: function(request) { new Ajax.Request(this.url, { method: 'get', parameters: { 'msg' : request }); } } var comet = new Comet(); comet.connect(); </script> </body> </html>
Download it
Here is the tar.gz archive of this demo.
If you liked this article please flattr me
- How to implement COMET with PHP
- 转:How to implement COMET with PHP
- How to implement COMET with PHP
- How to implement DynamicMBean with custom annotation
- How to Implement Add/Edit/Delete/View with PHP using Angular JS (Part-1)
- How to Implement Add/Edit/Delete/View with PHP using Angular JS (Part-2)
- How to implement popup Calendar dialog box with DataGrid
- How to implement scrolling image with javascript in web page
- How to implement fiber
- how to implement QAbstractScrollArea
- How to code APNS with PHP?
- How to implement "Find Target"
- How to: Implement Interface Events
- Example - how to implement INotifyDataErrorInfo
- How to implement double currency
- How to implement MySQL Sharding
- How to implement segment tree
- How to post JSON to PHP with curl
- linux I2C二
- 忠告:学精一门技术,才是立足社会之本
- Jigloo插件的安装
- Word 快速插入双直线,Word插入水平线,Word插入波浪线,Word插入实心线
- VB计算汉字笔画数代码
- How to implement COMET with PHP
- 疑难声卡驱动,疑难显卡驱动,疑难网卡驱动便捷安装方法,根据硬件ID查找设备驱动
- QQ2009 JAVA 触屏版,JAVA QQ最新触屏版,E680 QQ2009, 7070C QQ2009
- 大公司的一个部门干不过小公司?
- 摩托罗拉USB充电问题,E680G V3等摩托罗拉MOTO手机 摩托罗拉充电器,普通充电器改摩托罗拉充电器,自制摩托充电器。
- Palm Treo 650 万能红外控制软件 Omni Remote
- 克隆系统无法关机,ghost系统装网卡驱动时卡死
- XP无法装UAA声卡驱动,XP无法安装声卡驱动,High Definition Audio无法安装驱动,XP SP3 UAA声卡驱动安装
- UIlabelz自适应高度和换行