php使用COMET實現服務器向瀏覽器推送數據

Comet技術能夠讓後臺服務器在瀏覽器沒有發起請求的狀況下,向用戶瀏覽器推送數據。這種技術比傳統的ajax技術更具備時效性。傳統的ajax中,服務器在數據發生變更時不能即時通知瀏覽器。用戶的瀏覽器必須向後臺發出請求(如點擊一個連接或者使用持久的ajax),才能得到最新的數據。

下面解釋使用php實現comet技術。下面是兩種不一樣的方式實現comet:第一種基於hidden<iframe>,另外一種基於傳統的ajax non-returning請求。第一個例子簡單地實現了在瀏覽器上不斷地輸出時間戳,第二個例子簡單實現了在線聊天功能。 javascript

iframe技術實現comet:時間戳demo

咱們須要: php

  • 一個php腳原本處理持久化的http請求(backend.php) html

  • 一個html文件來加載相關的javascript代碼,來展現服務器返回的數據(index.html) java

  • prototype這個庫文件能夠幫助咱們寫一些簡單的js代碼 ajax

下面是這個demo的流程: 瀏覽器

後臺的php腳本

這個腳本會進入一個死循環,在客戶端鏈接時,不斷向客戶端輸出時間戳信息。下面是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>';
            ob_flush();//原文代碼沒有這一行
            flush(); // used to send the echoed data to the client
            sleep(1); // a little break to unload the server CPU
    }

?>

客戶端html腳本

客戶端的html文件中,首先會在<head>標籤中加載prototype庫文件,接着建立用來展現時間戳信息的div標籤<div id="content"></div>,最後建立了一個comet對象,經過它鏈接到後臺腳本。 app

comet對象會建立一些不可見的iframe標籤,這些iframe是爲了建立持續的鏈接到後臺腳本的http鏈接。Notice:這個腳本不會處理client瑜server之間的鏈接問題。 dom

<!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>

下載源碼

點擊tar.gz下載此demo。 ui

傳統ajax實現comet:小型在線聊天demo

實現這個demo,咱們須要:

  • 一個用來存儲、交換數據的文件(data.txt)

  • 一個php腳本,用來處理持續化的http請求(backend.php)

  • 一個html文件,用來加載javascript代碼,展現服務器發送過來的數據

  • prototype這個庫文件能夠幫助咱們寫一些簡單的js代碼

後臺的php腳本

後臺的腳本完成兩個功能:

  • 接收用戶的輸入,將新消息保存到data.txt中

  • 執行死循環,監測data.txt是否發生變化

下面是代碼:

繼續閱讀->;
相關文章
相關標籤/搜索