理解 comet

一、comet 由來

當服務器端數据發生變化時,客戶端如何即時得到通知呢?這個就是Comet誕生的背景。

1、傳統方法

定時刷新,就是隔一個時間段瀏覽器刷新一次。

2、長輪詢(long-polling)

使用Ajax隔一段時間就去服務器查詢是否有更新,但是多長時間去查詢成了問題。因為性能和即時性造成了嚴重的反比關系。

前面的方法都不太好,我們就可能想到使用服務器推送至客戶端的應用,也就是下面的技朮comet。

二、comet 定義

一種WEB服務器推的應用技朮(Server Push)

Web服務器端

1、利用Ajax與服務器建立http長連接查詢是否有數据更新,

2、服務器收到一個連接如果沒有數据更新就阻塞這個連接不要返回給客戶端,

3、直到有新數据再返回給客戶端。

Web客戶端

1、發起的連接一旦被返回,或者超時就再次建立http長連接。

這樣就能保証數据的即時更新,以及盡量減少服務器的計算工作。

三、comet 特點

1、優點:實時性好,性能好

2、缺點:長期占用連接,喪失了無狀態高並發的特點。

四、php + jquery 實現 comet

1、JavaScript 代碼

 //上次數据保存時間

 var timestamp = 0;

 //獲取數据是否有錯誤

 var error = false;

 //長連接服務器,請求數据

 function long_connect(){

  $.ajax({

   data : {‘timestamp’ : timestamp},

   url : ‘get.php’,

   type : ‘get’,

   timeout : 0,

   success : function(response){

    //格式化返回數据

    var data = eval(‘(‘+response+’)’);

    //設置錯誤信息

    error = false;

    //設置上次數据保存時間

    timestamp = data.timestamp;

    //顯示獲取的數据

    $(“#content”).append(‘‘ + data.msg + ‘‘);

   },

   error : function(){

    //設置錯誤信息

    error = true;

    //5s后再次連接服務器

    setTimeout(function(){ long_connect();}, 5000);

   },

   complete : function(){

    if (error)

    {

     //如果有錯,5s后再次連接服務器

     setTimeout(function(){long_connect();}, 5000);

    }

    else

    {

     //如果獲取信息成功,則再次連接服務器

     long_connect();

    }

   }

  });

 }

 //保存數据到服務器

 function savedata(msg){

  $.ajax({

   data : {‘msg’ : msg},

   type : ‘post’,

   url : ‘put.php’

  })

 }

 //頁面加載完成,即建立長連接,獲取數据

 $(document).ready(function(){

  long_connect();

 });

2、保存數据

//保存數据的文件

$file_name  = dirname(__FILE__).’/data.txt’;

// 獲取傳遞的數据

$msg = isset($_POST[‘msg’]) ? $_POST[‘msg’] : “;

//如果保存數据不為空,保存數据,不返回

if ($msg != “)

{

 file_put_contents($file_name,$msg);

}

3、獲取數据

//保存數据的文件

$file_name  = dirname(__FILE__).’/data.txt’;

//獲取文件上傳更新時間

$last_modif_time = isset($_GET[‘timestamp’]) ? $_GET[‘timestamp’] : 0;

//獲取文件更新時間

$current_modif_time = filemtime($file_name);

//如果文件沒有被修改,則阻塞不返回

while ($current_modif_time <= $last_modif_time)

{

 //阻塞10ms

 usleep(10000);

 //清除文件狀態緩存

 clearstatcache();

 //獲取文件更新時間

 $current_modif_time = filemtime($file_name);

}

//返回數据

$response = array();

//獲取文件內保存的內容

$response[‘msg’] = file_get_contents($file_name);

//獲取文件修改時間

$response[‘timestamp’] = $current_modif_time;

//返回json格式的數据

echo json_encode($response);

//刷新輸出緩沖

flush();

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>