php伺服器推技術的聊天室

WBOY
發布: 2016-07-25 08:57:32
原創
898 人瀏覽過
有幾個概念之間的關係,這裡補充下: 在程式碼中使用ob_start(), 就相當於在php.ini中使用output_buffering=on一樣,使用伺服器快取。 在程式碼中使用ob_end_flush() 就相當於在php.ini中使用output_buffering = false一樣,關閉伺服器快取。
  1. //chat.php
  2. header('cache-control: private');
  3. header('Content-Type : text/html; charset=utf-8');
  4. ?>
  5. 函數submitChat(obj) {
  6. obj. submit();
  7. document.getElementsByName('content')[0].value = '';
  8. }
複製程式碼

儲存使用者提交的聊天內容 簡單版本:

  1. $content = trim($_POST['content']);
  2. if ($content) {
  3. $fp = fopen('./chat.txt', 'a');
  4. fwrite($fp, $content . "n");
  5. fclose($fp);
  6. clearstatcache() ;
  7. }
  8. ?>
複製程式碼

主要的HTTP長連接部分,chat_content.php檔案:

  1. header('快取控制:私有');

  2. header('內容-Type: text/html; charset=utf-8');
  3. //測試設定30秒逾時,一般會設定比較時間。
  4. set_time_limit(30);
  5. //這行是為了搞定IE這個BT
  6. echo str_repeat(' ', 256);
  7. ob_flush();

  8. flush();
  9. $line = 0;

  10. $totalLine = 0;
  11. while (!$fp->eof() ) {
  12. $fp->current();
  13. $totalLine++;
  14. $fp->next();
  15. }
  16. $fp ->seek($totalLine);

  17. $i = $totalLine - 1;
  18. while (true) {
  19. if (!$fp->eof()) {
  20. if ($ content = trim($fp->current())) {
  21. echo '
    ';
  22. echo htmlspecialchars($content);
  23. echo "
" ;
  • flush();
  • $fp->next();
  • $i++;
  • }
  • } else {
  • $fp->seek($i - 1);
  • $fp->next();
  • }
  • {
  • //這裡可以加入心跳偵測後退出循環
  • }
  • usleep(1000);
  • }
  • ?>
  • 複製程式碼

    代碼說明: 06. 設定一個超時時間,由於要保持HTTP長連接,這個時間肯定要比較長,可能要幾個小時吧,上面提到的文章裡也有說明,這種HTTP長連接只能打開兩個,由於瀏覽器的限制。另外 其實即使你設定了一個永不逾時,其實上伺服器部分(如Apache)的設定檔也可能對HTTP請求設定了最長等待時間,所以也可能效果會不是你想的,一般預設可能都是15分鐘超時。如果 有興趣可以自己嘗試修改。

      09. 這裡輸出了一段空白,主要是手冊上已經說明了,IE瀏覽器在前面256個字符是不會直接輸出的,所以我們先隨便輸出些空白,以便讓後面的內容輸出來,可能其他瀏覽器也有其他 瀏覽器的設置,具體可以查看PHP手冊的frush函數的說明。接下去11、12行就是強制把這些空白符號丟給瀏覽器輸出。

      13. ~ 20. 這裡主要是為了計算檔案行數,以便從這一行後面開始讀取內容。

      接下去的while循環就是一個死循環了,就是循環輸出文件內容,每次判斷是否到達文件末尾,如果有用戶寫入文件,則當前檢測肯定不是文件末尾,就將該行讀取出來輸出,否則將指 針往前移動一行,繼續循環,每次等待1000微秒,

      39. 如果一直保持長連接,那麼即使客戶端斷開,服務端也不一定能知道客戶端已經斷開,所以這裡可能還需要做一些心跳記錄,比如每個用戶保持一個心跳flag,每格幾秒鐘更新一下 最後心跳時間,當偵測最後時間很久沒更新後,推出這個死循環,關閉這個HTTP連線。

    示範範例2: 傳統的B/S結構的應用程序,都是採用"客戶端拉"結束來實現客戶端和伺服器端的資料交換。 本文將透過結合Ticks,來實現一個伺服器推的PHP聊天室簡單構想。

    PHPer,尤其是用過set_cookie, header的,一定看過這樣的提示訊息:"Warning: Cannot modify header information - headers already sent by.....", 這是因為透過HTTP協定通信 ,封包會包含兩個部分,一個是Header,一個是data。 一般來說,都是先Header部分,在Heaer部分指明了Data部分的長度,然後使用\r\n\r\n來表示header部分結束,接下來是Data部分。

    當有任何輸出時,Header部分就發送了,此時,再想header函數來改變一些Header部分的域訊息,就會得到上面的提示訊息。 一個簡單的方法就是使用output_buffering。讓它來快取伺服器的輸出,不要太早將Header部分發給客戶端。 那麼,如果不使用output_buffering,是不是就可以實現,每當伺服器有輸出,就立即傳送給客戶端呢? 做個如下試驗:

    1. //設定php.ini中output_buffering=0 或使用ob_end_flush()關閉快取
    2. set_time_limit(0); 🎜>for($i=0;$i echo "Now Index is :". $i;
    3. sleep(1);
    4. }
    5. ?>
    複製程式碼
    結果發現,還是要等到腳本全部執行完以後,才能一次看到所有的結果。為什麼呢? 這是因為只是解決了快取問題,但還有一個緩衝問題,PHP會緩衝程式的輸出。 所以,此時還需要調用,flush(), 來強制使得PHP將所有的程式輸出傳送給客戶端。

    1. //設定php.ini中output_buffering=0

    2. ob_end_flush();//關閉快取
    3. set_time_limit(0);

    4. for($i=0;$i echo "Now Index is :". $i;
    5. flush();
    6. sleep(1);
    7. }
    8. ?>
    複製程式碼

    複製程式碼

    現在是不是看到了,不斷有伺服器的資料顯示出來?

    1 2 下一頁 尾頁


    來源:php.cn
    本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    熱門教學
    更多>
    最新下載
    更多>
    網站特效
    網站源碼
    網站素材
    前端模板