Ajax、服务器推和双向通信

本文由大丰哥参考自:

congdepeng博文http://congdepeng.iteye.com/blog/1169481、

stackoverflow问题"What are Long-Polling, Websockets, Server-Sent Events (SSE) and Comet?"Steve Chambers的答案

gemantic博文http://gemantic.iteye.com/blog/1553385

李刚《疯狂HTML5/CSS3/Javascript讲义》第18章

MOZILLA DEVELOPER NETWORK文档https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events?

小胡子哥博文http://www.cnblogs.com/hustskyking/p/3479336.html

感谢以上诸位前辈。

#什么是Ajax?

异步的JavaScript和XML(Asynchronous?JavaScript and XML)。浏览器允许JavaScript脚本向服务器发送一个HTTP请求而又无需重新加载页面。

这个功能主要由浏览器完成,浏览器提供这个功能给JavaScript脚本来调用,然后浏览器根据规则来回调脚本去处理响应。所以Ajax中其实浏览器是最大苦力。JavaScript可以换成其他脚本,交换数据也不一定是XML格式的,所以XML也是可有可无的。所以Ajax中除了A(Asynchronous)以外,其他几个字母都是浮云。

#浏览器是如何封装异步调用功能给JavaScript调用?

浏览器把这个功能封装在一个JavaScript对象 window.XMLHttpRequest 里面。这个对象就像一个代理,为JavaScript调用提供接口。

XMLHttpRequest提供了一些方法以及属性如下:

  • open(method,?url,?async):调用的参数配置
  • send([string]):将请求发送到服务器
  • onreadystatechange( ):由浏览器回调的方法,由开发人员编写
  • readyState:HTTP请求的状态
  • status:HTTP状态码

浏览器其实只是封装了一个Socket调用而已。XMLHttpRequest?作为封装这个?Socket?的?Proxy。

Socket的工作流程:

创建Socket对象-->建立连接-->发送数据-->接受数据-->处理接受到的数据-->关闭连接

Ajax的工作流程:

创建XMLHttpRequest对象-->设置连接的相关参数open(method,url,async)-->发送数据send([string])-->处理接受到的数据onreadystatechange( )

对比Socket和Ajax的工作流程,你会发现经过浏览器封装后的Socket调用更加简单,你不需要主动建立连接和关闭连接,只需要设置好相关的参数,同时写好如何处理接受到的数据的方法,那么关于Socket以及HTTP协议的细节问题就交给浏览器去做了。

Ajax调用的基本代码示例:

var
xmlhttp = new
XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
// xmlhttp.readyState
// xmlhttp.status
}
xmlhttp.open("GET", "/ajax/demo_get.php", true);
xmlhttp.send();

Ajax做轮询:

var
polling = function(url, type, data){
var
xhr = new
XMLHttpRequest(),
type = type || "GET",
data = data || null;

xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
receive(xhr.responseText);
xhr.onreadystatechange = null;
}
};

xhr.open(type, url, true);
//IE的ActiveXObject("Microsoft.XMLHTTP")支持GET方法发送数据,
//其它浏览器不支持,已测试验证
xhr.send(type == "GET" ? null : data);
};

var
timer = setInterval(function(){
polling();
}, 1000);

Ajax发送的内容仍然是基于HTTP协议的请求。理论上Ajax发送一个请求和你在地址栏里面输入请求是一模一样的。服务器应该根本就不知道什么是Ajax,服务器只处理HTTP请求。

#什么是Reverse Ajax

先谈谈为什么要Reverse Ajax:

因为HTTP协议是无状态的,即请求完数据后就关闭了连接。如果服务器有新的数据,浏览器是无法知道的,必须主动去查询才能知道。又因为Ajax是基于HTTP的,所以Ajax请求在缺省情况下也是无状态的,且只能从客户端向服务器端发出请求。(可以通过使用技术模拟服务器端和客户端之间的响应式通信来绕过这一限制)。

为了尽快地获得服务器端事件,我们只能使用粗暴的HTTP轮询来完成任务。轮询的间隔(两次请求相隔的时间)必须尽可能地小。

  • 优点:很容易实现,不需要任何服务器端的特定功能,且在所有的浏览器上都能工作。
  • 缺点:如果间隔减小的话,客户端浏览器就会发出更多的请求,这些请求中的许多都不会返回任何有用的数据,而这将会白白地浪费掉带宽和处理资源。

用?firebug 调试一下 weibo.com 的网络请求可以发现,微博用的是轮询来实现消息提醒的,应该是用set timer隔个0.7分钟去服务器进行查询。和即时通信的web应用不同,微博提醒实时性要求不高,所以用轮询方式比较合理,没有必要用长连接。

?

有一个叫捎带轮询(piggyback polling)的实现方式是一种比轮询更加聪明的做法。它会删除掉所有非必需的请求(没有返回数据的请求)。不存在时间间隔,客户端在需要的时候向服务器端发送请求。不同之处在于响应的那部分上,响应被分成两个部分:对请求数据的响应和对服务器事件的响应,如果任何一部分有发生的话,在实现piggyback技术时,通常针对服务器端的所有Ajax请求可能会返回一个混合的响应。

  • 优点:没有不返回数据的请求。因为客户端对何时发送请求做了控制,对资源的消耗较少。该方法也可用在所有的浏览器上,不需要服务器端的特殊功能。
  • 缺点:当累积在服务器端的事件需要传送给客户端时,你却一点都不知道,因为这需要一个客户端行为来请求它们。

?
?

我们回到原点,为什么要关闭连接然后再不停的建立连接呢?为什么不建立一个时间非常长的连接呢?

因为以前的HTTP 1.0不支持长连接,所以我们不得已只能轮询!到了HTTP 1.1开始支持长连接,我们可以建立一个长连接来完成这个目的。下面介绍长连接。

#Comet

Comet 是一种?Web?应用程序架构。可以说,它不是一种技术,而是一种思想,只是这种思想采用了已有的技术去实现。在这种思想里,客户端(Client)不需要显式地向服务器端(Server)发出请求,Server会在其数据发生变化的时候主动将数据异步发送给Client,从而使Client能够及时更新数据并呈现给用户。它不同于传统的Web,也不同于当前流行的Ajax,这种思想非常架构思想非常适合event-driven(事件驱动)式的Web应用和对交互性及实时性要求很强的应用,比如股票交易,聊天室,Web IM,网游等。

?

最常见的有下面两种方式:

1. HTTP?长轮询(HTTP Long Polling):Javascript在处理完服务器返回的信息后再次发出请求,重新建立连接。不同于一般的Ajax,Javascript请求Server,无数据时Server不中断请求(still loading),在一定时间内获取到数据后,返回请求,又在获取数据后再次发出请求,由此轮询。需要注意的是请求的间隔时间以及每次请求的最长Loading时间。做个比喻,如果轮询是排队买东西,那么长轮询就是排队上厕所。买东西的话,丢下钱就可以拿东西走了,但是上厕所就不一样,有些人说不定便秘半个小时都出不来。如果只用轮询去做Web通信,那服务器就鸭梨山大了,它需要一直做接受和断开HTTP请求的操作。就像卖热销产品的店员就没有公共厕所管理员那么轻松。

?

  • 优点:异步请求;无需浏览器任何插件支持;采用Ajax技术,兼容性强;
  • 缺点:会产生大量的通信量,只能通过增加轮询的时间间隔来减轻Server的压力;

ajax实现长轮询时,就是在xhr对象关闭连接的时候马上又给接上:

var
							longPoll = function(type, url){
															var
																	xhr = new
																					XMLHttpRequest();

    xhr.onreadystatechange = function(){
																											// 状态为 4,数据传输完毕,重新连接
								if(xhr.readyState == 4) {
														receive(xhr.responseText);            xhr.onreadystatechange = null;

																						//递归
								longPoll(type, url);         }    };

    xhr.open(type, url, true);    xhr.send();}

只要服务器断开连接,客户端马上连接,不让有一刻的休息时间,这就是长轮询。

?

2. Iframe结合Htmlfile流(streaming)HTTP?流(HTTP Streaming):通过在页面上嵌入一个隐藏的Iframe,设置其src属性为一个长连接的请求,Server采用flush方式将数据作为前端Javascript函数的参数传递;

  • 优点:不会有很大的通信量,而且数据接收非常及时,并且无中断;
  • 缺点:会产生进度条的Loading状态并一直存在,用户使用体验很不好。在Google Talk中,通过Htmlfile Active解决了IE下的进度条显示问题;保持长期链接也非常耗服务器资源;

反向Ajax的目的是允许服务器端向客户端推送信息。这样如果服务端有数据更新,就可以及时推送给客户端。

#HTML5?Server-Sent Events

Server-Sent Events是一个从服务器到浏览器的单向推送,实际上是将Comet技术进行了标准化。Server-Sent Events规范"定义了API来打开一个HTTP连接,通过该连接能够获取从服务器推送的通知"。Server-Sent Events包含新的 Javascript 对象?EventSource 和新的 MIME 类型 text/event-stream,这个 MIME 类型定义了事件框架格式。

EventSource 代表的是接收事件的客户端的终点。客户端通过创建 EventSource 对象来打开一个 event stream。创建 EventSource 对象时,该对象接收一个事件来源的 URI 作为其构造函数的参数。当每次收到新的事件数据时 onmessage 事件处理器会被调用。

Server-Sent Events是基于HTTP streaming的。如上所述,响应会一直打开,当服务器端有事件发生的时候,事件会被写入响应中。

#HTML5 ?WebSocket

WebSocket 启用了双向的全双工通信信道,许多浏览器(Firefox、Google Chrome 和 Safari)都已对此做了支持。连接会保持在活动状态,可以使用 JavaScript 来写入和接收数据,就像是在使用一个原始的TCP套接口一样。WebSocket URL的起始输入是ws://或是wss://(在SSL上),从这个ws和wss上可以想到,WebSocket?已经不是建立在?HTTP?协议之上了!

  • 优点:功能强大、双向、低延迟,且易于处理错误。不像 Comet 长轮询那样有许多的连接。它的API 也很容易使用,无需另外的层就可以直接使用,而Comet 则需要一个很好的库来处理重连接、超时、Ajax请求、确认以及选择不同的传输(Ajax 长轮询和 jsonp 轮询)。
  • 缺点:是一个来自 HTML5 的新规范,还没有被所有的浏览器支持。没有请求作用域(request scope)(因为?WebSocket?是一个?TCP?套接口而不是一个?HTTP?请求),有作用域的请求服务,比如说 Hibernate 的 SessionInViewFilter,就不太容易使用。

var
						ws = new
										WebSocket("ws://www.example.com:8888");

ws.onopen = function(evt){};ws.onmessage = function(evt){
																														deal(evt.data);};ws.onclose  = function(evt){};

//ws.close();

Ajax、服务器推和双向通信

时间: 2024-10-20 19:06:42

Ajax、服务器推和双向通信的相关文章

Comet4J AJAX 服务器推送框架

Comet4J(Comet for Java)是一个纯粹基于AJAX(XMLHTTPRequest)的服务器推送框架,消息以JSON方式传递,具备长轮询.长连接.自动选择三种工作模式. 功能特性 推送消息广播. 推送定向消息. 提供连接上线前.上线.下线前.下线.发送消息等多种可处理事件. 消息缓存机制,确保长轮询工作模式下不丢失消息. 客户端正常下线,服务端可立即感知. 客户端异常停止工作,服务端可定时检查并感知. 以注册通道应用的方式,让开发者对框架功能进行扩展,实现自己的应用. 框架特性

HTTP 笔记与总结(9)分块传输、持久链接 与 反向 ajax(comet / server push / 服务器推技术)

反向 ajax 又叫 comet / server push / 服务器推技术 应用范围:网页聊天服务器,例如新浪微博在线聊天.google mail 网页聊天 原理:一般而言,HTTP 协议的特点是,连接之后断开连接(服务器响应 Content-Length,收到了指定 Length 长度的内容时,也就断开了).在 HTTP 1.1 协议中,允许不写 Content-Length,比如要发送的内容长度确实不知道,此时需要一个特殊的 Content-Type:chunked,叫做分块传输,只有当

【DWR系列02】-DWR逆向Ajax即服务器推送

.literal { background-color: #f2f2f2; border: 1px solid #cccccc; padding: 1px 3px 0; white-space: nowrap; color: #6d180b; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 16px } 一.简单例子直观认识 1.1 模拟场景 假定项目中需要新增一个功能,管理员发布某些信息

服务器推Comet长轮询的方式与普通AJAX不断请求的方式的区别

当我们想要在浏览器实时显示某些数据,如何实现? 实现的方式有多种,最简单的既是设置一个间隔,AJAX不断发送请求,这种方式最明显的缺陷不管有没有新数据都会一直发送请求,而且这个间隔如果设置的长,及时性太差,如果间隔设置的短,每个客户端都在不断发送大量请求,影响服务器性能 还有一种是利用服务器推的技术,基于长轮询的方式,如图所示: 一开始会觉得,这个也是在不断的请求服务器端,和普通AJAX不断请求有什么区别?这是还未了解长轮询的流程.深入研究了下,发现区别很大 长轮询大致流程为: 客户端通过AJA

Spring之WebSocket网页聊天以及服务器推送

Spring之WebSocket网页聊天以及服务器推送 转自:http://www.xdemo.org/spring-websocket-comet/ /Springframework /Spring之WebSocket网页聊天以及服务器推送 1. WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duplex). 2. 轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客服端

服务器推送

WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议.WebSocket通信协议于2011年被IETF定为标准RFC 6455,WebSocketAPI被W3C定为标准. 在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道.两者之间就直接可以数据互相传送. 背景 现在,很多网站为了实现推送技术,所用的技术都是轮询.轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然

HTML5中的服务器‘推送’技术 -Server-Sent Events

转帖:http://www.developersky.net/thread-63-1-1.html 一直以来,HTTP协议都是严格遵循Request-Response模型的.客户端发送一个Request到服务器,服务器对Request作出响应并将Response发送回客户端.也就是说,所有的互动都是由客户端发起的,服务器不会发起任何互动.为了创建互动性更强的web应用程序,AJAX出现了,AJAX实现了一个动态的从Server获取数据的方法.通过使用AJAX,浏览器通过XMLHttpReques

Comet:基于 HTTP 长连接的“服务器推”技术

“服务器推”技术的应用 传统模式的 Web 系统以客户端发出请求.服务器端响应的方式工作.这种方式并不能满足很多现实应用的需求,譬如: 监控系统:后台硬件热插拔.LED.温度.电压发生变化: 即时通信系统:其它用户登录.发送信息: 即时报价系统:后台数据库内容发生变化: 这些应用都需要服务器能实时地将更新的信息传送到客户端,而无须客户端发出请求.“服务器推”技术在现实应用中有一些解决方案,本文将这些解决方案分为两类:一类需要在浏览器端安装插件,基于套接口传送信息,或是使用 RMI.CORBA 进

DWR3.0 服务器推送及解惑

前言 环境搭建 建立工程 jar包填装 下载dwrjar 下载commons-loggingjar 项目目录 webxml dwrxml java文件 jsp页面 调试运行 文字展示 图片展示 解惑篇 关于自动生成的js文件 如何配置页面脚本 客户端怎么调用服务器端方法 总结 前言 昨天晚上偶然咋慕课网上看到了一个DWR的视频,一开始我还以为是DreamWaver的缩写,后来发现我错了,原来人家是Direct Web Remoting的缩写. DWR说白了是一个用于改善web页面与Java类交互