zz How to implement COMET with PHP

今天在群里遇到一个人,说到web方面的server push的功能。当时无法理解,搜了搜资料。贴过来给大家看看。原贴里面图片连接失效了,我搜了一个,不知道是不是这个图。

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 realtime 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:

How COMET works

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代码
  1. <?php  
  2. header("Cache-Control: no-cache, must-revalidate");  
  3. header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");  
  4. flush();  
  5. ?>  
  6. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">  
  7. <html xmlns="http://www.w3.org/1999/xhtml">  
  8. <head>  
  9.   <title>Comet php backend</title>  
  10.   <meta http-equiv="Content-Type" content="text/html; charset=utf-8"  />  
  11. </head>  
  12. <body>  
  13.  
  14. <script type="text/javascript">  
  15.   // KHTML browser don't share javascripts between iframes  
  16.   var is_khtml = navigator.appName.match("Konqueror") || navigator.appVersion.match("KHTML");  
  17.   if (is_khtml)  
  18.   {  
  19.     var prototypejs = document.createElement('script');  
  20.     prototypejs.setAttribute('type','text/javascript');  
  21.     prototypejs.setAttribute('src','prototype.js');  
  22.     var head = document.getElementsByTagName('head');  
  23.     head[0].appendChild(prototypejs);  
  24.   }  
  25.   // load the comet object  
  26.   var comet = window.parent.comet;  
  27. </script>  
  28.  
  29. <?php  
  30. while(1) {  
  31.   echo '<script type="text/javascript">';  
  32.   echo 'comet.printServerTime('.time().');';  
  33.   echo '</script>';  
  34.   flush(); // used to send the echoed data to the client  
  35.   sleep(1); // a little break to unload the server CPU  
  36. }  
  37. ?>  
  38. </body>  
  39. </html> 

The client script (HTML)

This HTML document first load the prototype library in the tag, then it create the tag that will contains the server timer , 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.

xhtml代码
  1. <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> 
  2. <script type="text/javascript" src="prototype.js"></script> 
  3. <div id="content">The server time will be shown here</div> 
  4. <script type="text/javascript"> 
  5. var comet = {  
  6.   connection   : false,  
  7.   iframediv    : false,  
  8.  
  9.   initialize: function() {  
  10.     if (navigator.appVersion.indexOf("MSIE") != -1) {  
  11.  
  12.       // For IE browsers  
  13.       comet.connection = new ActiveXObject("htmlfile");  
  14.       comet.connection.open();  
  15.       comet.connection.write("<html>");  
  16.       comet.connection.write("<script>document.domain = '"+document.domain+"'");  
  17.       comet.connection.write("</html>");  
  18.       comet.connection.close();  
  19.       cometcomet.iframediv = comet.connection.createElement("div");  
  20.       comet.connection.appendChild(comet.iframediv);  
  21.       cometcomet.connection.parentWindow.comet = comet;  
  22.       comet.iframediv.innerHTML = "<iframe id='comet_iframe' src='./backend.php'></iframe>";  
  23.  
  24.     } else if (navigator.appVersion.indexOf("KHTML") != -1) {  
  25.  
  26.       // for KHTML browsers  
  27.       comet.connection = document.createElement('iframe');  
  28.       comet.connection.setAttribute('id',     'comet_iframe');  
  29.       comet.connection.setAttribute('src',    './backend.php');  
  30.       with (comet.connection.style) {  
  31.         position   = "absolute";  
  32.         left       = top   = "-100px";  
  33.         height     = width = "1px";  
  34.         visibility = "hidden";  
  35.       }  
  36.       document.body.appendChild(comet.connection);  
  37.  
  38.     } else {  
  39.       
  40.       // For other browser (Firefox...)  
  41.       comet.connection = document.createElement('iframe');  
  42.       comet.connection.setAttribute('id',     'comet_iframe');  
  43.       with (comet.connection.style) {  
  44.         left       = top   = "-100px";  
  45.         height     = width = "1px";  
  46.         visibility = "hidden";  
  47.         display    = 'none';  
  48.       }  
  49.       comet.iframediv = document.createElement('iframe');  
  50.       comet.iframediv.setAttribute('src', './backend.php');  
  51.       comet.connection.appendChild(comet.iframediv);  
  52.       document.body.appendChild(comet.connection);  
  53.  
  54.     }  
  55.   },  
  56.  
  57.   // this function will be called from backend.php    
  58.   printServerTime: function (time) {  
  59.     $('content').innerHTML = time;  
  60.   },  
  61.  
  62.   onUnload: function() {  
  63.     if (comet.connection) {  
  64.       comet.connection = false; // release the iframe to prevent problems with IE when reloading the page  
  65.     }  
  66.   }  
  67. }  
  68. Event.observe(window, "load",   comet.initialize);  
  69. Event.observe(window, "unload", comet.onUnload);  
  70. </script> 

 

Download it

Here is the tar.gz archive of this demo.

Online demo

Here is the online demo.
From: http://kerphi.zeitoun.net/articles/comet_and_php/

 

 

Tags: php
上一篇: 复杂的心情
下一篇: NS2仿真

相关日志推荐
[转载]PHP header函数用法
AJAX与PHP传递中文数据
YII框架的几个问题
[转载]apache和php乱码问题的解决方法
ajax中文乱码问题解决(PHP)

0 条留言

发表评论

  
  
   (点击图片更换验证码)
点击刷新验证码