Flex+PHP反向推送(长轮询)

反向推送技术现在很流行, 而长轮询是促成反为推送的关键技术之一.

//如果假定轉載本文請注明出處,免的出現版權紛爭,我无喜歡看到那種轉載了自身之著作卻不注明出處的食指
Seven{See7di#Gmail.com}
HTTP 协议的功成名就不必置疑。它是
Internet上绝大多数音置换的功底。然而,它吗起部分局限性。特别是,它是凭状态、单为的情商。请求被发送至
Web 服务器,服务器处理要并作回一个响应
—仅此而已。请求必须由客户机发出,而服务器则只能在针对要的应中发送数据。这足足会影响多种的
Web应用程序的实用性。典型的事例就是聊天程序。另外还有一对事例,例如角之比分或电子邮件程序。

HTTP的这些局限性也是其取一定成功的由来。请求/响应周期而它们化了经的模型,即每个连使用一个线程。只要会高效为要提供劳动,这种方式就
有光辉的可伸缩性。每秒钟可以拍卖大量底请求,只待利用少量的服务器即好拍卖非常死数额的用户。对于群藏的
Web应用程序,例如内容管理体系、搜索应用程序和电子商务站
点等等而言,这非常适合。在以上任何一样栽
Web应用程序中,服务器提供用户要的数量,然后关门连接,并释放那个线程,使的得呢其它请求服务。如果提供初始数据之后按可能存在交互,那么将连接
保持吗开辟状态,因此线程就无克释放出来,服务器也尽管无可知也无数用户服务。

而,如果想在针对要做出响应并发送初始数据之后,仍然维持与用户的彼此呢?在
Web 早期,这等同沾时利用
meta刷新实现。这将机关指示浏览器在指定秒数之后再也装载页面,从而支持简陋的轮询(polling)。这不单是同一种不好的用户体验,而且一般效率不
常低下。如果没新的数量要出示在页面及也?这时不得不再次呈现同样的页面。如果对页面的更改很少,并且页面的大多数没转为?同样,不管是否来必要,
都得重新请与得页面及之整整情节。

Ajax
的说明与流行改变了上述情景。现在,服务器可以异步通信,因此不用再度请整个页面。现在可以展开增量式的换代。只待采取XMLHttpRequest
轮询服务器。这项技艺一般给叫作Comet。这项技艺有有的变体,每种变体具有不同的性能与可伸缩性。我们来探这些不同风格的
Comet。

Comet 风格

Ajax 的产出如 Comet
成为可能。HTTP的才为性质可中地加以规避。实际上有一部分差之艺术可以绕了就一点。您或许曾经猜到,支持
Comet 的极致轻之方法是轮询(poll)。使用XMLHttpRequest
向服务器发调用,返回后,等待一段落固定的时日(通常用 JavaScript 的
setTimeout函数),然后再度调用。这是相同桩好大的技术。例如,大多数
webmail 应用程序就是经这种技术在电子邮件至时显得电子邮件的。

这项技术发生长处也出欠缺。在这种场面下,您要快速回到响应,就比如任何其它
Ajax请求一样。在呼吁中必须有同等截间歇。否则,连续不停的乞求会冲垮服务器,并且这种状况下显然不具可伸缩性。这段间歇而应用程序产生一个延时。
暂停的光阴更长,服务器上之初数据就是用更进一步多的年华才会抵客户机。如果缩短暂停时间,又以重新面临冲垮服务器的高风险。但是另一方面,这分明是最好简便易行的实
现Comet 的艺术。

今日应该指出,很多口看轮询并无属 Comet。相反,他们当 Comet
是针对性轮询的局限性的一个缓解方 案。最广大的 “真正的”Comet
技术是轮询的一律种变体,即长轮询(longpolling)。轮询与长轮询之间的关键分在服务器花多丰富的岁月作出响应。长轮询通常将连接保持一如既往段落于长
的时
—通常是数秒钟,但是也说不定是千篇一律分钟还还增长。当服务器上发生有事件不时,响应被发送并随着关闭,轮询立即又开。

加上轮询相对于一般轮询的亮点在于,数据要可用,便立马从服务器发送到客户机。请求或等待于丰富的年月,期间从来不其它数据返回,但是要是产生了新的数量,它
将即刻为发送至客户机。因此尚未延时。如果你使用过因 Web
的闲聊程序,或者声称 “实时”
的其他程序,那么它非常可能就是使用了这种技术。

脚我不怕Flex和PHP来举例说明一下,常轮询如何实现.

首先将瞬间PHP端的代码,很简单 

<?php
//timeout in seconds
$timeout = 60;

// log start time
$start_time = time();

// get messge from local file
function get_msg(){
    return file_get_contents(‘msg.txt’);
}

// get message
$last_msg = get_msg();

// start the loop
while (true){
    // get current time
    $current_time = time();
    
    // check if we are timed out
    if ($current_time – $start_time > $timeout){
        echo ‘timeout! no new message!’;
        break;
    }
    
    // get latest message
    $current_msg = get_msg();
    
    // check if the message has been changed
    if ($last_msg != $current_msg){
        echo $current_msg;
        break;
    }
    // sleep 1 sec
    sleep(1);
}

浅析者的代码, 其实原理就是是以php中尽一个巡回,
每次循环的时刻失去拜访服务器上之数,
可以是数据库也足以是一个文本文件,这里运用文本文件,
然后判断文本文件的内容是否更新了,如果更新了则用数据返回给客户端.
在循环当中我们放入了
sleep(1)函数让代码每次循环的时候抛锚1秒钟,这样不至于过度吃服务器CPU的资源.

下面是flex端的代码

<?xml version=”1.0″ encoding=”utf-8″?>
        <![CDATA[
            // request object
            private var req:URLRequest;
            
            // loader object
            private var loader:URLLoader;
            
            // timer
            private var timer:Timer;
            
            [Bindable]
            private var count:Number = 0;            
            
            // do some initializing
            private function init():void{
                req = new
URLRequest(‘http://127.0.0.1:8080/long\_polling.php’);
                loader = new URLLoader();
                
                loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,
onStatusChange);
                loader.addEventListener(Event.COMPLETE, onComplete);
                loader.addEventListener(IOErrorEvent.IO_ERROR,
onIOError);
                
                timer = new Timer(1000);
                timer.addEventListener(TimerEvent.TIMER, onTimer, false,
0, true);
                
            }
            
            // update the second count
            private function onTimer(event:TimerEvent):void{
                count ++;
            }
            
            // start the request
            private function startRequest():void{
                count = 0;
                loader.load(req);
                timer.start();
                this.txtLogs.text += ‘Request started!\n’;
            }
            
            // status changed
            private function
onStatusChange(event:HTTPStatusEvent):void{
                this.txtLogs.text += ‘Status changed to ‘+
String(event.status)+’\n’;
            }            
            
            // result returned
            private function onComplete(event:Event):void{
                this.txtLogs.text += ‘Completed! Result is
‘+String(event.currentTarget.data)+’\n’;
                this.txtLogs.text += ‘Start another request!\n’;
                this.startRequest();
            }
            
            // error handler
            private function onIOError(event:IOErrorEvent):void{
                this.txtLogs.text += ‘IO Error: ‘+String(event)+’\n’;
                this.stopRequest();
            }
            
            // stop the request
            private function stopRequest():void{
                count = 0;
                this.txtLogs.text += ‘Request stopped!\n’;
                this.txtLogs.text +=
‘<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>\n’
                this.timer.stop();
                this.loader.close();
                
            }
        ]]>

我们新建一个flex项目, 然后以界面及放4个空中, 两单按钮, 一个凡始于要,
一个是终止请求, 还有一个label用来显示当前恳求所花之时刻,
最后又放开一个TextArea来显示log.

告的法则也一样略, 通过URLLoader和URLRequest来促成,
和通常的http请求并随便星星样.不过在同等不成呼吁获取到结果的时节(走至onComplete()函数),
我们用重开另外一差询问,通过这种方式我们即便可效仿出一个近乎与C/S架构的网络连接,
而服务端上的外更新则会自行推送至客户端了.

相关文章