书名:Web异步与实时交互——iframe AJAX WebSocket开发实战
ISBN:978-7-115-42385-6
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
• 著 赵 振
责任编辑 赵 轩
• 人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
• 读者服务热线:(010)81055410
反盗版热线:(010)81055315
本书以介绍iframe、AJAX和WebSocket三项Web异步交互技术为基本主线,进一步对iframe、AJAX和WebSocket分别通过轮询、长轮询、长连接和推送方式,实现Web交互时的性能进行测试和深入分析。
第1章介绍了异步、实时Web交互技术中的关键概念和技术,阐述了本书的写作思路。
第2章和第3章介绍了iframe实现模拟异步交互的关键技术、工作原理,以及基于iframe和长连接实时交互方式实现的案例。
第4章和第5章讲解了AJAX实现异步交互的关键技术、工作原理,以及基于AJAX和长连接实时交互方式实现的案例。
第6章和第7章阐述了WebSocket实现主动推送交互的关键技术、工作原理,以及基于WebSocket和推送实时交互方式实现的案例。
第8章在前文的基础上,对iframe、AJAX和WebSocket相关异步交互技术,及配合使用的轮询、长轮询、长连接及推送四种实时交互方式的多种Web交互方案,进行测试和深入谈论,分析了不同方案的数据传输有效性、数据传输实时性和不同响应方式对服务器性能的影响三种性能指标。
异步交互、实时交互作为Web交互技术中的热点和难点,越来越多地被研究和使用。
在Web异步交互方面,AJAX作为当今非常热门和流行的异步传输技术,已被行业广泛采用。但在AJAX这种真正的异步传输技术出现之前,一般使用iframe模拟实现异步传输,目的是保证网页在不刷新的情况下进行数据传输更新网页内容,从而提高用户的体验。目前,iframe实现模拟异步传输这一技术,仍然经常被程序员使用。
而WebSocket技术,作为HTML 5标准中的亮点,真正实现了“服务器推”的概念,实际上是对AJAX技术的跨越式优化。但由于目前该技术较新(AJAX应用较成熟),且受浏览器支持、WebSocket对服务器端性能等方面因素的影响,尚未被大范围应用,因此,出现了这些异步传输技术在Web应用市场上被共同使用的情况,我们认为有必要对这3种异步技术进行深入地研究和分析。
另外,在Web实时交互方面,经常会使用轮询、长轮询、长连接及推送这4种Web交互方式。iframe、AJAX和WebSocket作为三项Web异步交互技术,可使用这4种Web交互方式,异步、实时地实现信息的传输。
其中,轮询是不断使用基于HTTP协议的Web交互方式对服务器端数据进行获取,但在满足实时更新服务器端信息的同时有一定的延迟;长轮询、长连接及推送都可以满足实时更新服务器端信息,属于实时Web交互技术的范畴。
虽然这4种Web交互方式应用广泛,但目前尚没有相关书籍、资料对其进行清晰地定义、深入地分析和测试,以至于由于不了解这些不同技术方案的性能区别,不能在方案制订初期,就对方案路线选择给出明确、正确的设计。
综上所述,很有必要对iframe、AJAX和WebSocket相关异步交互技术及配合使用的轮询、长轮询、长连接及推送4种实时交互方式进行介绍和深入分析。
以下两类读者可能会对本书感兴趣。
软件工程人员在熟悉使用一种技术后,如果想进阶,成长为高级程序员不仅要实现技术,还要会根据系统需求,选择、设计相适应的技术方案,这就要求深入了解几种技术的特性、使用方法、服务器的响应方式及不同方案的相关性能区别。想深入了解一下相关的技术知识,肯定需要去网上大量查找资料,而网上的论坛的资料多是以评论为主,复制粘贴他人帖子的,是不全面的、不准确的,想迅速掌握这些技术有非常大的难度。因此,具备一定Web交互软件开发经验的、想进阶的程序员想进阶,本书可能是你需要的。
本书落脚点在于对Web异步、实时交互进行技术知识讲解、技术应用上手,公司新入职的程序员、具备一定软件专业知识的大学生等初学者,都可以使用这本书来达到学习、理解和进阶的目的。从内容上来看,这本书包括相关基础关键技术的介绍,由最简核心代码形成的实例程序(介绍其工作原理和使用方法),分别使用3种技术实现的3个实用案例。在此基础上,本书深入地对3种技术性能及其服务器响应4种方式进行实验测试、分析等方面的内容。初学者首先能够看懂,并可以从基础到深入,达到迅速学习、理解并上手使用异步传输系列相关技术的目的。
因此,本书在设计内容上,既照顾了初学者快速学习、全面了解、上手使用的需求,兼顾了有经验的软件工程人员迅速进阶、深入理解的需求。
编者
Web交互开发中的异步、实时Web交互技术,是当前Web应用技术研究领域的新热点之一。本章首先对传统Web交互技术进行了简单介绍,进一步从Web异步交互技术和Web实时交互方式两个角度,对Web交互开发中的异步、实时等系列技术进行了概要介绍、分析,并给出了本书的思路及内容安排。
HTTP协议(Hyper Text Transport Potocol,超文本传输协议),是基于服务器/客户端模式的无连接、无状态的协议。基于HTTP协议的Web应用中,所有的请求是由客户端发起的,服务器处于被动响应的地位。然而,服务器却相当于是信息的发布者,当有新信息产生时,服务器并不能主动将新信息发送给客户端,必须等待客户端主动发起访问请求建立连接后才能发送给客户端。
当遇到实时监控、即时通信、在线互动等的Web交互开发需求(如设备监控、聊天室、股票行情等需求)时,传统的Web交互技术显得力不从心。最初,客户端只能通过设定自动刷新时间的方式(如使用<meta>标签,或通过JavaScript代码进行设定)使浏览器主动刷新,向服务器端发送请求,来获取服务器端的新信息。这种方式有以下几个缺点。
(1)刷新页面的时候,网页会呈现一片空白,影响用户的体验。
(2)在多数情况下页面中需要更新的信息只是很小一部分,其他信息不变。这样,在刷新整个页面时,传送了额外的信息,使得页面刷新速度变慢,并增加了网络的负担。
(3)由于客户端隔一段时间才发送一次请求,并不能实时获得服务器端的新信息,有一定延迟。
其中,问题(1)(2)可以通过1.2节中介绍的Web异步技术来解决;问题(3)可以通过1.3节中介绍的Web实时交互技术来解决。
随着Web交互技术的发展,出现了使用iframe模拟异步传输,来实现局部刷新页面获取数据的功能,从而解决1.1节中的问题(1)(2)。iframe是一种HTML标记,它会创建包含另外一个文档的内联框架,通过iframe框架可以在当前页面中显示其他页面的信息。这时将iframe的src属性设置为对另外一个页面的连接请求,并在当前页面中通过JavaScript动态更新iframe的内容,就可以将服务器端的数据响应到客户端,而不会出现主页面一片空白,等待刷新的现象。并且,仅刷新iframe框架而不是主页面,也减少了页面刷新的内容,这在一定程度上提高了页面刷新速度。
然而,iframe是通过刷新隐藏框架,获取响应后通过DOM技术对主页内容进行更新——这实际上是模拟的异步交互,并非真正的异步交互。随着Web交互技术的发展,一个真正意义上的异步交互技术应运而生——AJAX。这种技术通过异步通信和响应,来完成页面的局部刷新,以此改善传统Web应用中大量不必要的整页刷新,从而提高响应的效率,让用户更快地得到操作结果,减少中间的等待时间。同时AJAX作为浏览器端技术,极大地改善页面的表现和交互方式,可以让传统的Web应用程序界面具备桌面应用程序般的表现力,从而为用户提供更人性的服务。
但是,iframe、AJAX都是基于HTTP协议进行Web交互。HTTP协议的工作模式对于其构建实时Web应用存在诸多的限制——只能先由客户端提交请求,服务器端响应请求,并非是由服务器向客户端进行主动推送。随着HTML 5标准的推出,这一状况得到了改善,其提出了一种新的浏览器服务器通信协议——WebSocket协议。通过该协议可以在浏览器和服务器之间构建一条全双工的通信连接,可以支持服务器端向客户端主动推送信息,实现实时刷新页面的功能。WebSocket协议不仅解决了1.1节中的问题(1)(2),还解决了1.1节问题(3)中提出的实时性问题。
综上所述,AJAX作为当今非常热门、流行的异步传输技术,已被行业广泛采用。但在AJAX这种真正的异步传输技术出现之前,一般使用iframe模拟实现异步传输,目的是保证网页在不刷新的情况下进行数据传输更新网页内容,从而提高用户的体验。目前,iframe实现模拟异步传输这一技术,仍然经常被程序员使用。而WebSocket技术,作为HTML 5标准中的亮点,真正实现了“服务器推”的概念。其实际上是对AJAX技术的跨越式优化。但由于目前该技术较新(AJAX应用较成熟)、浏览器支持、WebSocket对服务器端性能的影响等方面的因素,尚未被大范围应用。因此,出现了这些异步传输技术在应用市场上被共同使用的情况,有必要对这3种异步技术进行深入的研究和分析。
如何实时获取服务器端的最新数据,是Web实时交互关注的内容。在介绍Web实时交互方式前,先来具体了解HTTP的通信机制,为之后概念的精准定义做铺垫。HTTP通信过程可分为4步。
第1步:HTTP是基于传输层的TCP协议,在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器在TCP层建立连接。在TCP层进行“三次握手”之后,建立了TCP连接,此时HTTP就可以进行传输了(注意,由于HTTP为无连接、无状态的协议,在本书之后的章节内容中,若提到打开、保持或关闭连接时,其中的“连接”均指TCP层的连接)。
第2步:建立连接后,客户端发送一个请求给服务器。
第3步:服务器接到请求后,给予相应的响应信息。
第4步:客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户端与服务器断开连接。
需要注意的是,在第4步服务器响应请求后是否断开连接,要看协议版本(HTTP 1.0协议在服务器响应后,会关闭连接;HTTP 1.1协议在服务器响应后,默认会保持连接,直到超时或出错),要看是否客户端主动请求断开连接、要看是否服务器端主动断开连接,要看是否出错或是否连接超时等对连接进行断开。
在很多情况下,保持住连接,有以下两点好处。
(1)客户端和服务器可以继续通过保持住的连接发送请求及响应,节省了为每个请求建立新连接所需的时间、资源。这在客户端内存、CPU等资源比较有限,或服务器端需要处理大量并发请求时,保持连接,重用该连接的传输通道是非常有必要的技术手段。
(2)当客户端向服务器端发送请求后,服务器端若无需要响应给客户端的最新信息时,阻塞该请求不进行响应,并保持住连接;等到服务器端有信息需要响应该客户端时,使用保持住的连接进行响应。该技术手段属于实时Web交互技术,可以有效解决1.1节问题(3)中实时更新服务器端信息的需求。
基于上述基础知识,在大量分析相关Web实时交互技术的基础上,总结并清晰定义4种Web交互技术,即轮询、长轮询、长连接及推送。
轮询:客户端定时发送请求,服务器端接收到客户端请求后,马上进行响应,并关闭连接。
长轮询:客户端发送请求,服务器端接收到客户端请求后进行阻塞,并保持连接;当服务器端有数据需要响应时,使用保持住的连接进行响应,并关闭连接。
长连接:客户端发送请求,服务器端接收到客户端请求后进行阻塞,并保持连接;当服务器端有数据需要响应时,使用保持住的连接进行响应,并保持住连接。
推送:客户端与服务器端建立连接后,服务器端可以直接将数据推送给客户端。
其中,轮询是不断、循环使用基于HTTP协议的传统Web交互方式对服务器端数据进行获取,但正如1.1节所述,其在满足实时更新服务器端信息时有一定延迟。除此之外,长轮询、长连接及推送都可以满足实时更新服务器端信息,属于实时Web交互技术的范畴。
本节中介绍的iframe、AJAX和WebSocket是三项Web异步交互技术,可使用轮询、长轮询、长连接及推送4种Web实时交互方式,与服务器进行交互。
本书以介绍iframe、AJAX和WebSocket三项Web异步交互技术为基本主线,在此基础上,进一步对iframe、AJAX和WebSocket分别通过轮询、长轮询、长连接和推送方式,实现对Web交互时的性能进行测试和深入分析。
章节内容安排为,第2章到第7章主要介绍上述三项技术的相关知识、关键代码解析以及案例实现,重点在技术知识讲解、技术上手应用方面;第8章,是以前7章内容为基础,对相关理论、技术细节、不同方案进行进一步深入地测试、分析,目的在于使读者更加清晰、深入地了解三项Web异步交互技术及4种Web交互技术,在面对不同系统开发需求时,可以根据本书提供的测试分析中的各项性能指标,进行综合考虑,并最终设计、确定技术方案。
最初,客户端只能通过设定自动刷新时间的方式(如使用<meta>标签,或通过JavaScript代码进行设定)使浏览器主动刷新,向服务器端发送请求,以轮询的方式获取服务器端的最新信息。通常情况下,用户要获取最新的信息,必须刷新浏览器中的整个页面来获取服务器端的响应数据。但是,在多数情况下页面中需要更新的信息只是很小一部分,其他信息不变。这样,在刷新整个页面时,不仅传送了额外的信息,增加了网络的负担,且刷新页面的同时,网页会呈现一片空白,给用户的视觉体验带来严重的影响。
iframe技术模拟实现了异步交互技术,有效解决了上述问题。本章介绍了利用iframe实现模拟异步交互技术的相关基础知识、工作原理、关键代码及基本案例。
服务器端响应时间是用户体验中关键的一部分。为了解决之前技术更新页面时,服务器端响应时间长、页面刷新速度慢、用户体验度差等问题,使用iframe模拟异步交互技术来实现局部刷新页面获取数据。iframe是一种HTML标签,它会创建包含另外一个文档的内联框架。通过iframe框架可以在当前页面中显示其他页面的信息。这时将iframe的src属性设置为对另外一个页面的长连接请求,并在当前页面中通过JavaScript动态更新iframe的内容,即可将服务器端响应的数据无刷新显示在主页面。
通过iframe实现的模拟异步交互技术,可以应用于聊天室、实时状态监控、股票行情等需要实时刷新的应用场景。
DOM(Document Object Model)即文档对象模型。DOM是与系统平台和编程语言无关的W3C官方标准。W3C对DOM的定义是:“一个与系统平台和编程语言无关的接口,程序和脚本可以通过这个接口动态地对文档的内容、结构和样式进行访问和修改。”
DOM本质上是一个树形结构模型,它将整个页面映射为一个由层次节点组成的文档。每个节点都有一系列的子节点;每个子节点都有唯一的父节点;节点又分为元素节点和文本节点两种,元素节点中有属性。DOM可以根据节点之间的关系对文档进行操作。
程序开发人员可以利用DOM技术实现动态地创建文档,遍历文档结构,添加、修改、删除文档内容等。DOM技术实现了用户页面动态地变化,使得页面的可交互性大大地增强。
目前,DOM包括以下3个部分。
Core DOM——Core DOM是针对任意结构文档的标准对象模型,它所定义的对象已经可以表达出任何HTML和XML文档中的数据。
HTML DOM——HTML DOM是针对HTML的文档对象模型,它将所有的HTML元素定义为对象,Web开发人员可以通过对象的方法来访问并操作HTML文档。
XML DOM——XML DOM是针对XML的文档对象模型,它定义了针对XML的标准对象集合以及访问和操作XML文档的方法。
用户可以利用HTML DOM提供的方法和属性,实现节点的创建、复制、插入、删除、替换、查找以及遍历等操作。
(1)HTML DOM方法
其语法格式如下:
reference = document.createElement(element)
语法格式如下:
reference = document.createTextNode(text)
语法格式如下:
reference = node.cloneNode(deep)
语法格式如下:
reference = element.appendChild(newChild)
语法格式如下:
reference = element.insertBefore(newChild,targetNode)
语法格式如下:
reference = element.removeChild(node)
语法格式如下:
reference = element.replaceChild(newChild,oldChild)
语法格式如下:
element.setAttribute(attributeName,attributeValue)
语法格式如下:
element = document.getElementById(ID)
语法格式如下:
elements = document.getElementsByTagName(tagName)
(2)HTML DOM属性
语法格式如下:
name = node.nodeName
nodeName属性会根据节点类型返回相应的值。
语法格式如下:
integer = node.nodeType
表2-1 nodeType常用节点类型描述
元素类型 |
nodeType值 |
---|---|
元素 |
1 |
属性 |
2 |
文本 |
3 |
注释 |
8 |
文档 |
9 |
语法格式如下:
value = node.nodeValue
语法格式如下:
nodeList = node.childNodes
语法格式如下:
reference = node.firstChild
语法格式如下:
reference = node.lastChild
语法格式如下:
reference = node.parentNode
iframe是超文本标记语言(HTML)的一个标签,是用来实现框架的一种方式。和常见的frame一样,用它来对网页结构进行拆分,使相应网页部分在刷新时保持不变。iframe相对frame更加灵活,它可以内嵌到网页的任意地方,实现在一个网页里内嵌另一个网页。使用方法简单,将它的src属性指向想要包含的文件即可,并且可以根据情况指定其宽(width),高(height)等属性。
语法格式如下:
<iframe src="value">
语法格式如下:
< iframe onload="script">
当客户使用get方式请求Servlet时,Web容器调用doGet方法处理请求,doGet方法的定义代码如下:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { }
doPost方法是用来处理使用post方式提交的表单,不能处理客户端浏览器直接访问的方式。doPost方法的定义代码如下:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { }
使用Servlet的doGet和doPost方法来处理iframe提交的请求。
在实现iframe模拟异步交互技术中,利用iframe内嵌网页的特性,实现网页间数据的“隐形”传输:通过对主页面中隐藏的iframe内嵌网页不断进行刷新,可以不断地向服务器端提交请求,服务器端通过相应Servlet的doPost/doGet方法处理并响应。客户端所获得的响应数据,通过JavaScript调用DOM模型,可以将其更新于主页面中,而不需要刷新整个父窗口的内容,当前页面其他的数据状态得以保留,同时减少了数据的传输量。
下面使用iframe模拟异步交互技术,使用轮询的方式,实现数字累加功能。
客户端代码主要包含3个部分:定时向服务器端发送请求、接收服务器端返回的信息及展示服务器端返回的信息。
关键代码如下所示:
<html>
<head>
<script type="text/javascript">
function addMessage(counts){ //将服务器端发送回的信息更新到文本框
var messageElement = document.getElementById("message");//获取id为message的文本框
messageElement.innerHTML += counts; //将新信息添加到文本框
}
function f(){
if(true){
var iframeElement = document.getElementById("iframe");
iframeElement.src = iframeElement.src;
setTimeout(f, 30*1000);
}
}
setTimeout(f, 30*1000); //定时器,实现每30秒调用一次函数f
</script>
</head>
<body>
<iframe id="iframe" src="test"></iframe>//通过src指向一个Servlet类,实现对服务器端的请求
<style="display:none">
<div id="message" style="height:400px; width:100%; overflow:scroll;"></div>
</body>
</html>
为实现客户端定时向服务器发送请求,通过在客户端添加一个定时器,定时时间为30×1000(以毫秒计算时间,即30秒)。当时间到达30秒后,通过调用函数f来更改iframe的src属性,重新向服务器发送请求,也就实现了轮询。
服务器返回给客户端的是一段js代码,该js代码调用了addMessage函数。该函数的作用是将新信息添加到id为message的div中。
服务器端的关键代码主要是在Servlet中,通过doGet方法来处理来自客户端的请求。
关键代码如下所示:
public class TestServlet extends HttpServlet{//子类TestServlet继承父类HttpServlet
private int counts = 0; //私有成员变量counts
@Override//覆盖父类的方法
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();//输出内容到客户端,就是用户的网页
Out.println("<script>parent.addMessage('"+ counts +"<br>')</script>");//调用show中的addMessage
counts++;
}
}
接收到来自客户端的请求后,首先会通过response.getWriter()方法来获得一个响应的输出流,然后将counts计数信息连同包含它的js代码发送回客户端,客户端通过执行调用主页面的addMessage函数将counts信息进行显示。
程序开始运行后,运行效果如图2-1所示。
图2-1 程序运行后网页的最初效果
当程序运行30秒后,数字增加1,运行效果如图2-2所示。
图2-2 系统运行30秒后的网页效果
程序每运行30秒,数字增加1,运行效果如图2-3所示。
图2-3 系统连续运行的网页效果