`
happy90
  • 浏览: 62209 次
  • 性别: Icon_minigender_1
  • 来自: 中国
社区版块
存档分类
最新评论

PHP服务端推送技术Long Polling【转】

阅读更多

Long Polling与Polling概述

服务端推送技术应用越来越普遍,应用范围也越来越宽广,技术解决方案也越来越成熟且丰富。很多SNS网站的chat功能就有用到了Long Polling技术。比如fackebook, kaixin001。

Long Polling原理其实很简单,也很讨巧。与Polling相比,Long Polling客户端也许不会马上收到来自服务端的响应,需要等待一些时间(直到有新消息,或者连接timeout了等等)。同样的,客户端也不再需要定时向服务发送请求了,而是直到收到服务端响应之后,或者连接丢失之后,客户端接着马上请求客户端。这里,我打个比方,传统的Polling一般是由C向S询问:”有我的信件吗?”。S接到询问之后,会立即查询,并且把查询结果告诉C,不管有没有C的信件,要码回复:”嗯,你有X封信。”,要码回复:”没,没有你的信”.而Long Polling更像是这样,C向S发出询问:”有我的信件吗?”,S开始查询,如果有则回复C:”嗯,有你x封信”。如果没有,则不作任何回复,而是让C等着,自己一遍一遍地查询是否有订阅者的信。换句话说:当S收到C的查询请求之后,Polling则只查询一次,并且把查询结果告诉C;而Long Polling收到请求之后,则会一遍一遍地查询,直到有消息才会响应C,不然一直hold Client。

Long Polling相较传统的Polling而言,最大的实惠在于:减少了请求次数。举个例子,假定一个用户每2小时内,有可能收到2条新消息。如果采用传通的Polling方式,每30秒发向服务端发送一次查询请求的话。则在这2小时内,服务器需要处理240(60*60*2/30)次请求,其中至少有238次请求是没有实际意义的。试想,如果是10000的并发量的话,这种浪费是很惊人的。相较而方,Long Polling没有那么浪费服务器资源来处理这些没有实际意义的请求。

Polling

传统的Polling实现方式比较单一,由客户端javascript脚本定时发送http请求。服务端脚本如下:

<?php
header("Expires: Sun, 19 Nov 1978 05:00:00 GMT");
header("Last-Modified: ". gmdate("D, d M Y H:i:s") ." GMT");
header("Cache-Control: store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", FALSE);
 
$msg = get_msg();
if ($msg) {
 echo $msg;
} else {
 echo '0';
}
?>

上面是一个传统polling简单的服务端脚本。很简单,收到客户端请求后,服务端马上执行脚本查询,并且立即响应客户端。客户端等待的时间很短,客户端唯一要做的事情就是定时向服务端发出查询请求。下面是请求时,通过tcpdump抓到的包:

1>17:49:03.533760 IP 192.168.0.98.4383 > devhome.http: S 3235664319:3235664319(0) win 65535 <mss 1460,nop,nop,sackOK>
2>17:49:03.534336 IP devhome.http > 192.168.0.98.4383: S 2018732723:2018732723(0) ack 3235664320 win 5840 <mss 1460,nop,nop,sackOK>
3>17:49:03.533841 IP 192.168.0.98.4383 > devhome.http: . ack 1 win 65535
4>17:49:03.534404 IP 192.168.0.98.4383 > devhome.http: P 1:781(780) ack 1 win 65535
5>17:49:03.534416 IP devhome.http > 192.168.0.98.4383: . ack 781 win 7020
6>17:49:03.535033 IP devhome.http > 192.168.0.98.4383: P 1:369(368) ack 781 win 7020
7>17:49:03.535110 IP devhome.http > 192.168.0.98.4383: F 369:369(0) ack 781 win 7020
8>17:49:03.535263 IP 192.168.0.98.4383 > devhome.http: . ack 370 win 65167
9>17:49:03.536105 IP 192.168.0.98.4383 > devhome.http: F 781:781(0) ack 370 win 65167
10>17:49:03.536111 IP devhome.http > 192.168.0.98.4383: . ack 782 win 7020

第1、2、3行,TCP三次握手,建立连接。
第4行,由192.168.0.98向服务端devhome发送httpd请求。
第5行,由服务端devhome确认收到了来自客户端192.168.0.98的http请求。
第6行,服务器响devhom响应客户端192.168.0.98刚才发的httpd请求。注意:特别注意一下第一列时间截,http请求与http响应的时间间隔很短,才0.001s
第7、8、9、10共4行,TCP四次挥手,断开连接。由服务端主动断开连接。

Long Polling

Long Polling较之Polling稍微有些不一样,Long Polling持续执行,以此延迟对客户端的响应。请查看代码:

<?php
header("Expires: Sun, 19 Nov 1978 05:00:00 GMT");
header("Last-Modified: ". gmdate("D, d M Y H:i:s") ." GMT");
header("Cache-Control: store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", FALSE);
//在$timeout之后,关闭连接,并且要求客户3秒后重新请求
for ($i = 0, $timeout = 60; $i < $timeout; $i++ ) {
 $msg = get_msg();
 if ($msg) {
     echo json_encode(array('t' => 'info' , 'c' => $msg));
     flush();
     exit(0);
 }  
 usleep(3000000);
}
echo json_encode(array('t' => 'refresh', 'c' => 3000));
flush();
?>

上面是Long Polling服务端代码。语意也很明了,如果有$msg,则会马上响应客户端请求,并且关闭该TCP连接。如果在$timeout之内,没有$msg,则会让客户端一直保持该TCP连接,不中断(关闭)。直到超过了$timeout(具体时间主要取决于$timeout * $usleep_time),服务端会要求客户端重新请求(重新建立TCP连接),同时关闭当前TCP连接。下面是通过 tcpdump抓到的包:

1>18:39:46.449563 IP 192.168.0.98.4407 > devhome.http: S 174149200:174149200(0) win 65535 <mss 1460,nop,nop,sackOK>
2>18:39:46.449587 IP devhome.http > 192.168.0.98.4407: S 938669730:938669730(0) ack 174149201 win 5840 <mss 1460,nop,nop,sackOK>
3>18:39:46.449692 IP 192.168.0.98.4407 > devhome.http: . ack 1 win 65535
4>18:39:46.450308 IP 192.168.0.98.4407 > devhome.http: P 1:793(792) ack 1 win 65535
5>18:39:46.450320 IP devhome.http > 192.168.0.98.4407: . ack 793 win 7128
6>18:42:46.521749 IP devhome.http > 192.168.0.98.4407: P 1:377(376) ack 793 win 7128
7>18:42:46.521825 IP devhome.http > 192.168.0.98.4407: P 377:412(35) ack 793 win 7128
8>18:42:46.521859 IP devhome.http > 192.168.0.98.4407: F 412:412(0) ack 793 win 7128
9>18:42:46.521997 IP 192.168.0.98.4407 > devhome.http: . ack 412 win 65124
10>18:42:46.522021 IP 192.168.0.98.4407 > devhome.http: . ack 413 win 65124
11>18:42:46.522965 IP 192.168.0.98.4407 > devhome.http: F 793:793(0) ack 413 win 65124
12>18:42:46.522970 IP devhome.http > 192.168.0.98.4407: . ack 794 win 7128

第1、2、3行,TCP三次握手,建立连接。
第4行,由192.168.0.98向服务端192.168.0.6发送http请求。
第5行,由192.168.0.6确认收到192.168.0.98刚刚发送的请求。
第6、7行,服务器host_6响应3分钟前客户端192.168.0.98发出的http请求。注意,第一列的时间截,第5行与第6行之差为3分钟。这与服务端脚本,客户端监控是相呼应的。
最后4行,TCP四次挥手,断开连接,同样由服务端devhome发起。

由上图可见(httpwatch绘制),正好验证了,响应客户端host_98的http请求,在3分钟之后。这也说明了,Long Polling与Polling的区别在于,客户端有可能需要等待更长时间才能收到服务端的响应。

原文:http://www.perfgeeks.com/?p=139

分享到:
评论
1 楼 niejun0205 2013-02-20  

相关推荐

    java服务端推送实例-pushlet-及中文问题

    Java服务端推送技术在Web应用中常常用于实现实时数据传输,例如聊天系统、股票更新、在线游戏等场景。Pushlet是一个基于Java的轻量级推送框架,它允许服务器主动向客户端推送信息,而非传统的HTTP请求-响应模式,即...

    服务端推技术 - Server-side Push 多示例

    服务端推技术,也称为Server-side Push,是一种网络通信模式,允许服务器主动向客户端推送数据,而无需客户端发起请求。这种技术在实时性要求较高的应用中尤为重要,如在线聊天、实时股票更新、游戏同步等。在传统的...

    后台推送php实现程序

    在PHP中,实现后台推送主要有两种常见方法:长轮询(Long Polling)和WebSocket。 1. **长轮询**: 长轮询是一种模拟双向通信的技术,它通过延长HTTP连接的生命周期来实现。客户端发送一个Ajax请求到服务器,...

    SignalR-实现web浏览器客户端与服务端的推送功能

    ### SignalR实现Web浏览器客户端与服务端的推送功能详解 #### 一、SignalR简介 SignalR 是一种强大的工具,用于构建实时应用,使得在 Web 浏览器客户端与服务端之间实现双向通信成为可能。它最初是由微软开发并...

    SignalR股票原理_服务端主动推送数据到所有客户端(广播)

    SignalR利用多种底层传输技术,如WebSocket、Server-Sent Events (SSE)、Forever Frame或Long Polling,根据浏览器和服务器的兼容性自动选择最佳方案。WebSocket提供双向通信,效率最高,但不是所有浏览器都支持。...

    服务器推送——PushLet的应用<二>

    结合MyEclipse的开发环境,可以快速搭建出高效、稳定的服务端推送系统。 总结,PushLet是实现服务器推送功能的一个实用工具,通过理解其工作原理和使用方法,开发者可以轻松地在Java应用中集成实时通信功能。同时,...

    JAVA消息推送源程序

    消息推送技术是指服务器主动向客户端发送信息的技术,常见的有长轮询(Long Polling)、WebSocket以及Comet等。 - **长轮询(Long Polling)**:客户端发起HTTP请求后,服务器保持连接直到有新消息到达才返回响应。这种...

    PushMessage JavaWeb聊天 推送 实现

    JavaWeb聊天推送实现主要涉及到的是实时通信技术,用于在服务器和客户端之间传递消息,使得用户能够在不刷新页面的情况下接收到新的信息。在这个场景下,"PushMessage"通常指的是服务器主动向客户端推送数据,而非...

    超过QQ的聊天服务端+客户端

    5. **实时性**:为了实现即时通讯,可能采用了Websocket或Long Polling等技术来实现实时双向通信。 6. **消息存储**:服务端可能有数据库设计,用于存储聊天记录、用户信息等,可能使用了MySQL、MongoDB或Redis等...

    signalR实时消息推送测试

    SignalR主要利用了HTTP长连接(Long Polling)、WebSockets、Server-Sent Events (SSE)、Forever Frame等多种技术,根据浏览器和服务器的兼容性自动选择最佳的连接方式。这样,即使是一些较旧或者不支持WebSockets的...

    一个更加完善的SignalR服务端,本人已经在实际项目中使用,聊天室接口已经全部定义,只需要实际的实现,同时集成了Quartz

    - **接收消息**:客户端订阅消息事件,当有新消息时,服务端通过 SignalR 推送。 - **加入/退出聊天室**:用户可以加入或离开特定的聊天室,服务端需要维护每个用户的房间状态。 - **历史消息获取**:新用户加入...

    SignalRForm20191114002203.rar

    SignalR 是一个 ASP.NET 库,它为实时通信提供...这个“SignalRForm20191114002203.rar”压缩包内容可能包含了在一个Windows Forms应用程序中使用SignalR的示例项目,其中服务端通过一个独立的控制台应用运行...

    HTML5WebSockets基础使用教程

    WebSockets可以替代LongPolling(PHP服务端推送技术),这是一个有趣的概念。客户端发送一个请求到服务器,现在,服务器端并不会响应还没准备好的数据,它会保持连接的打开状态直到最新的数据准备就绪发送,之后客户端...

    tomcat+comet实现终端与服务端同步的小例子

    总结来说,"Tomcat+Comet实现终端与服务端同步的小例子"是一个学习实时通信和服务器推送技术的好起点。通过这个例子,开发者可以了解如何利用现有Web服务器的特性,创建高效、实时的Web应用。同时,这也是对传统HTTP...

    asp.net mvc实现简单的实时消息推送

    在本文中,我们将讨论如何使用ASP.NET MVC实现简单的实时消息推送,特别是在标题和描述中提到的SignalR技术。 实时消息推送允许服务器主动向客户端发送数据,而不仅仅是响应客户端的请求。在ASP.NET MVC中,实现这...

    火山安卓多用户消息同步服务端源码.rar

    2. **多用户消息同步**:掌握消息同步的机制,如使用推送通知(Push Notification)、长轮询(Long Polling)、Websocket等技术,保证实时性。 3. **服务端开发**:涉及网络编程,如HTTP/HTTPS协议,以及处理并发...

    pushlet 扩充,sessionid 采用userid

    Pushlet 的工作原理通常基于长轮询(Long Polling)、 comet 技术或者WebSocket等,这些技术克服了HTTP协议的无状态性和请求-响应模型的限制,实现了服务器到客户端的数据实时推送。在sessionid采用userid后,服务端...

    asp.net server push 长连接

    ASP.NET Server Push 长连接技术是一种用于实时通信的技术,它允许服务器主动向客户端推送数据,而无需客户端频繁发起请求。这种技术在实时性要求较高的应用中,如在线聊天、股票更新、游戏同步等场景非常有用。传统...

Global site tag (gtag.js) - Google Analytics