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

反向推送技术未来可怜流行, 而长轮询是落到实处反向推送的关键技术之一.

//假诺要轉載本文請注解出處,免的出現版權紛爭,笔者不喜歡看到那種轉載了小编的创作卻不评释出處的人
Seven{See七di#Gmail.com}
HTTP 协议的打响不必置疑。它是
Internet上绝超越53%音讯交流的功底。可是,它也有1些局限性。越发是,它是无状态、单向的商议。请求被发送到
Web 服务器,服务器处理请求并发回3个响应
—仅此而已。请求必须由客户机发出,而服务器则不得不在对请求的响应中发送数据。那至少会潜移默化很多类别的Web应用程序的实用性。典型的例子正是聊聊程序。别的还有1部分例证,例如比赛的比分或电子邮件程序。

HTTP的那几个局限性也是它拿走一定成功的原故。请求/响应周期使它变成了经典的模子,即每一种连接使用叁个线程。只要能够高效为呼吁提供服务,那种方式就
有高大的可伸缩性。每分钟可以处理多量的央浼,只需采纳少量的服务器就足以处理不小数据的用户。对于众多种经营文的
Web应用程序,例如内容管理种类、搜索应用程序和电子商务站
点等等而言,那非凡适合。在以上任何一种
Web应用程序中,服务器提供用户请求的数码,然后倒闭连接,并释放那多少个线程,使之能够为其它请求服务。固然提供初阶数据今后仍也许存在交互,那么将连接
保持为开拓状态,由此线程就不能够释放出来,服务器也就无法为广大用户服务。

可是,如若想在对请求做出响应并发送初叶数据未来,仍旧保持与用户的并行呢?在
Web 早期,那点常采取meta刷新实现。那将自动提示浏览器在内定秒数之后再度装载页面,从而扶助简陋的轮询(polling)。那不单是1种不佳的用户体验,而且一般作用好低下。倘若未有新的数据要显示在页面上啊?那时不得不重新显示同样的页面。假诺对页面包车型客车改动很少,并且页面包车型地铁绝超越44%未曾成形吧?同样,不管是还是不是有不能缺少,
都得重复请求和获得页面上的漫天情节。

Ajax
的表明和流行改变了上述情景。今后,服务器能够异步通信,因而不要再一次请求整个页面。未来得以拓展增量式的更新。只需使用XMLHttpRequest
轮询服务器。这项技艺1般被称作Comet。那项技艺存在部分变体,各种变体具有差别的习性和可伸缩性。我们来看看这个差别风格的
Comet。

Comet 风格

Ajax 的产出使 Comet
成为大概。HTTP的单向性质可以使得地加以规避。实际上有1对不等的章程能够绕过这点。您只怕曾经猜到,支持Comet 的最不难的不二等秘书诀是轮询(poll)。使用XMLHttpRequest
向服务器发出调用,重临后,等待壹段固定的时间(平日使用 JavaScript 的
set提姆eout函数),然后再一次调用。那是壹项十二分普遍的技巧。例如,超越1/三webmail 应用程序就是由此那种技能在电子邮件到达时显得电子邮件的。

那项技艺有独到之处也有瑕疵。在那种景观下,您愿意连忙回到响应,就好像其余其余Ajax请求一样。在伸手之间必须有一段间歇。不然,一连不停的乞请会冲垮服务器,并且那种状态下显明不负有可伸缩性。那段间歇使应用程序发生三个延时。
暂停的小时越长,服务器上的新数据就须求越多的时刻才能抵达客户机。即便收缩暂停时间,又将再也面临冲垮服务器的高危害。可是另壹方面,那明显是最简便易行的实现Comet 的秘籍。

现在应该建议,很四个人以为轮询并不属于 Comet。相反,他们觉得 Comet
是对轮询的局限性的3个消除方 案。最常见的 “真正的”Comet
技术是轮询的1种变体,即长轮询(longpolling)。轮询与长轮询之间的重点差异在于服务器花多少长度的小时作出响应。长轮询平日将延续保持一段较长
的时刻
—常常是数分钟,不过也大概是壹分钟甚至越来越长。当服务器上发出有些事件时,响应被发送并随即关闭,轮询登时重新起始。

长轮询相对于壹般轮询的长处在于,数据要是可用,便立马从服务器发送到客户机。请求大概等待较长的时光,时期未有任何数据重回,但是只要有了新的数目,它
将登时被发送到客户机。因而并未有延时。假如您使用过基于 Web
的闲谈程序,大概声称 “实时”
的任何程序,那么它很可能正是行使了这种技能。

下边作者就Flex和PHP来举例说澳优(Ausnutria Hyproca)(Karicare)下,常轮询如何达成.

第3将弹指间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(一)函数让代码每一趟循环的时候抛锚一分钟,这样不至于过度消耗服务器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();
                
            }
        ]]>

大家新建3个flex项目, 然后在界面上放置6个空中, 多个按钮, 二个是初叶请求,
1个是终止请求, 还有一个label用来呈现当前呼吁所花的年华,
最终再放2个TextArea来呈现log.

请求的法则也1律不难, 通过U猎豹CS六LLoader和U瑞虎LRequest来兑现,
和平时的http请求并无两样.不过在2次呼吁获取到结果的时候(走到onComplete()函数),
大家供给再次起始另外三回询问,通过这种办法大家就可以模拟出一个接近与C/S框架结构的网络连接,
而服务端上的其余更新则会自动推送到客户端了.

相关文章