当前位置: 首页 > news >正文

网站可信度验证网站建设需要注意事项

网站可信度验证,网站建设需要注意事项,安阳河南网站建设,广州万户网络在过去的几年中#xff0c;web开发已经发生了很大的变化。现如今#xff0c;我们期望的是能够通过web快速、动态地访问应用。在这一新的文章系列中#xff0c;我们学习如何使用反 向Ajax#xff08;Reverse Ajax#xff09;技术来开发事件驱动的web应用#xff0c;以此来…在过去的几年中web开发已经发生了很大的变化。现如今我们期望的是能够通过web快速、动态地访问应用。在这一新的文章系列中我们学习如何使用反 向AjaxReverse Ajax技术来开发事件驱动的web应用以此来实现更好的用户体验。客户端的例子使用的是JQuery JavaScript库在这首篇文章中我们探索不同的反向Ajax技术使用可下载的例子来学习使用了流streaming方法和长轮询long polling方法的Comet。   前言   web开发在过去的几年中有了很大的进展我们已经远超了把静态网页链接在一起的做法这种做法会引起浏览器的刷新并且要等待页面的加载。现在需要 的是能够通过web来访问的完全动态的应用这些应用通常需要尽可能的快提供近乎实时的组件。在这一新的由五部分组成的文章系列中我们学习如何使用反 向AjaxReverse Ajax技术来开发事件驱动的web应用。   在这第一篇文章中我们要了解反向Ajax、轮询polling、流streaming、Comet和长轮询long polling学习如何实现不同的反向Ajax通信技术并探讨每种方法的优点和缺点。你可以下载本文中例子的相应源代码。   Ajax、反向Ajax和WebSocket   异步的JavaScript和XMLAsynchronous JavaScript and XMLAjax一种可通过JavaScript来访问的浏览器功能特性其允许脚本向幕后的网站发送一个HTTP请求而又无需重新加载页面。Ajax的出现已经超过了十年尽管其名字中包含了XML但你几乎可以在Ajax请求中传送任何的东西最常用的数据是JSON其与JavaScript语法很接近且消耗更少带宽。清单1给出了这样的一个例子Ajax请求通过某个地方的邮政编码来检索该地的名称。   清单1. Ajax请求举例 var url http://www.geonames.org/postalCodeLookupJSON?postalcode   $(#postalCode).val() country   $(#country).val() callback?;  $.getJSON(url, function(data) {  $(#placeName).val(data.postalcodes[0].placeName);});   在本文可下载的源代码中你可在listing1.html中看到这一例子的作用。   反向AjaxReverse Ajax本质上则是这样的一种概念能够从服务器端向客户端发送数据。在一个标准的HTTP Ajax请求中数据是发送给服务器端的反向Ajax可以某些特定的方式来模拟发出一个Ajax请求这些方式本文都会论及这样的话服务器就可以尽可能快地向客户端发送事件低延迟通信。   WebSocket技术来自HTML5是一种最近才出现的技术许多浏览器已经支持它Firefox、Google Chrome、Safari等等。WebSocket启 用双向的、全双工的通信信道其通过某种被称为WebSocket握手的HTTP请求来打开连接并用到了一些特殊的报头。连接保持在活动状态你可以用 JavaScript来写和接收数据就像是正在用一个原始的TCP套接口一样。WebSocket会在这一文章系列的第二部分中谈及。   反向Ajax技术   反向Ajax的目的是允许服务器端向客户端推送信息。Ajax请求在缺省情况下是无状态的且只能从客户端向服务器端发出请求。你可以通过使用技术模拟服务器端和客户端之间的响应式通信来绕过这一限制。   HTTP轮询和JSONP轮询   轮询polling涉及了从客户端向服务器端发出请求以获取一些数据这显然就是一个纯粹的Ajax HTTP请求。为了尽快地获得服务器端事件轮询的间隔两次请求相隔的时间必须尽可能地小。但有这样的一个缺点存在如果间隔减小的话客户端浏览器就会发出更多的请求这些请求中的许多都不会返回任何有用的数据而这将会白白地浪费掉带宽和处理资源。   图1中的时间线说明了客户端发出了某些轮询请求但没有信息返回这种情况客户端必须要等到下一个轮询来获取两个服务器端接收到的事件。   图1. 使用HTTP轮询的反向Ajax             JSONP轮询基本上与HTTP轮询一样不同之处则是JSONP可以发出跨域请求不是在你的域内的请求。清单1使用JSONP来通过邮政编码获取地名JSONP请求通常可通过它的回调参数和返回内容识别出来这些内容是可执行的JavaScript代码。   要在JavaScript中实现轮询的话你可以使用setInterval来定期地发出Ajax请求如清单2所示   清单2. JavaScript轮询 setInterval(function() {  $.getJSON(events, function(events) {    console.log(events);  });}, 2000);   文章源代码中的轮询演示给出了轮询方法所消耗的带宽间隔很小但可以看到有些请求并未返回事件清单3给出了这一轮询示例的输出。   清单3. 轮询演示例子的输出 [client] checking for events...[client] no event[client] checking for events...[client]2 events[event] At Sun Jun 0515:17:14 EDT 2011[event] At Sun Jun 0515:17:14 EDT 2011[client] checking for events...[client]1 events[event] At Sun Jun 0515:17:16 EDT 2011   用JavaScript实现的轮询的优点和缺点   1. 优点很容易实现不需要任何服务器端的特定功能且在所有的浏览器上都能工作。   2. 缺点这种方法很少被用到因为它是完全不具伸缩性的。试想一下在100个客户端每个都发出2秒钟的轮询请求的情况下所损失的带宽和资源数量在这种情况下30%的请求没有返回数据。   Piggyback   捎带轮询piggyback polling是一种比轮询更加聪明的做法因为它会删除掉所有非必需的请求没有返回数据的那些。不存在时间间隔客户端在需要的时候向服务器端发送请求。不同之处在于响应的那部分上响应被分成两个部分对请求数据的响应和对服务器事件的响应如果任何一部分有发生的话。图2给出了一个例子。   图2. 使用了piggyback轮询的反向Ajax   在实现piggyback技术时通常针对服务器端的所有Ajax请求可能会返回一个混合的响应文章的下载中有一个实现示例如下面的清单4所示。   清单4. piggyback代码示例 $(#submit).click(function() {  $.post(ajax, function(data) {    var valid  data.formValid;    // 处理验证结果    // 然后处理响应的其他部分事件    processEvents(data.events);  });});   清单5给出了一些piggyback输出。   清单5. piggyback输出示例 [client] checking for events...[server] form valid ? true[client]4 events[event] At Sun Jun 0516:08:32 EDT 2011[event] At Sun Jun 0516:08:34 EDT 2011[event] At Sun Jun 0516:08:34 EDT 2011[event] At Sun Jun 0516:08:37 EDT 2011   你可以看到表单验证的结果和附加到响应上的事件同样这种方法也有着一些优点和缺点   1. 优点没有不返回数据的请求因为客户端对何时发送请求做了控制对资源的消耗较少。该方法也是可用在所有的浏览器上不需要服务器端的特殊功能。   2. 缺点当累积在服务器端的事件需要传送给客户端时你却一点都不知道因为这需要一个客户端行为来请求它们。   Comet   使用了轮询或是捎带的反向Ajax非常受限其不具伸缩性不提供低延迟通信只要事件一到达服务器端它们就以尽可能快的速度到达浏览器端。 Comet是一个web应用模型在该模型中请求被发送到服务器端并保持一个很长的存活期直到超时或是有服务器端事件发生。在该请求完成后另一个长 生存期的Ajax请求就被送去等待另一个服务器端事件。使用Comet的话web服务器就可以在无需显式请求的情况下向客户端发送数据。   Comet的一大优点是每个客户端始终都有一个向服务器端打开的通信链路。服务器端可以通过在事件到来时立即提交完成响应来把事件推给客户端 或者它甚至可以累积再连续发送。因为请求长时间保持打开的状态故服务器端需要特别的功能来处理所有的这些长生存期请求。图3给出了一个例子。这一文章 系列的第2部分会更加详细地解释服务器端的约束条件。   图3. 使用Comet的反向Ajax   Comet的实现可以分成两类使用流streaming的那些和使用长轮询long polling的那些。   使用HTTP流的Comet   在流streaming模式中有一个持久连接会被打开。只会存在一个长生存期请求图3中的#1因为每个到达服务器端的事件都会通过这同一 连接来发送。因此客户端需要有一种方法来把通过这同一连接发送过来的不同响应分隔开来。从技术上来讲两种常见的流技术包括Forever Iframe隐藏的IFrame或是被用来在JavaScript中创建Ajax请求的XMLHttpRequest对象的多部分multi- part特性。   Forever Iframe   Forever Iframe永存的Iframe技术涉及了一个置于页面中的隐藏Iframe标签该标签的src属性指向返回服务器端事件的servlet路径。每 次在事件到达时servlet写入并刷新一个新的script标签该标签内部带有JavaScript代码iframe的内容被附加上这一 script标签标签中的内容就会得到执行。   1. 优点实现简单在所有支持iframe的浏览器上都可用。   2. 缺点 没有方法可用来实现可靠的错误处理或是跟踪连接的状态因为所有的连接和数据都是由浏览器通过HTML标签来处理的因此你没有办法知道连接何时在哪一端已被断开了。   Multi-part XMLHttpRequest   第二种技术更可靠一些是XMLHttpRequest对象上使用某些浏览器比如说Firefox支持的multi-part标志。Ajax请 求被发送给服务器端并保持打开状态每次有事件到来时一个多部分的响应就会通过这同一连接来写入清单6给出了一个例子。   清单6. 设置Multi-part XMLHttpRequest的JavaScript代码示例 var xhr  $.ajaxSettings.xhr();xhr.multipart true;xhr.open(GET, ajax, true);xhr.onreadystatechange  function() {  if (xhr.readyState  4) {    processEvents($.parseJSON(xhr.responseText));  }};xhr.send(null);   在服务器端事情要稍加复杂一些。首先你必须要设置多部分请求然后挂起连接。清单7展示了如何挂起一个HTTP流请求。这一系列的第3部分会更加详细地谈及这些API。   清单7. 使用Servlet 3 API来在servlet中挂起一个HTTP流请求 protected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {  // 开始请求的挂起  AsyncContext asyncContext  req.startAsync();  asyncContext.setTimeout(0);  // 给客户端发回多部分的分隔符  resp.setContentType(multipart/x-mixed-replace;boundary\   boundary \);  resp.setHeader(Connection, keep-alive);  resp.getOutputStream().print(-- boundary);  resp.flushBuffer();  // 把异步上下文放在列表中以被将来只用  asyncContexts.offer(asyncContext);}   现在每次有事件发生时你都可以遍历所有的挂起连接并向它们写入数据如清单8所示   清单8. 使用Servlet 3 API来向挂起的多部分请求发送事件 for (AsyncContext asyncContext : asyncContexts) {  HttpServletResponse peer  (HttpServletResponse)  asyncContext.getResponse();  peer.getOutputStream().println(Content-Type: application/json);  peer.getOutputStream().println();  peer.getOutputStream().println(new JSONArray()  .put(At new Date()).toString());  peer.getOutputStream().println(-- boundary);  peer.flushBuffer();}   本文可下载文件的Comet-straming文件夹中的部分说明了HTTP流在运行例子并打开主页时你会看到只要事件一到达服务器端虽然不同 步但它们几乎立刻会出现在页面上。而且如果打开Firebug控制台的话你就能看到只有一个Ajax请求是打开的。如果再往下看一些你会看到 JSON响应被附在Response选项卡中如图4所示   图4. HTTP流请求的FireBug视图   照例做法存在着一些优点和缺点   1. 优点只打开了一个持久连接这就是节省了大部分带宽使用率的Comet技术。   2. 缺点并非所有的浏览器都支持multi-part标志。某些被广泛使用的库比如说用Java实现的CometD被报告在缓冲方面有问题。例如一些 数据块多个部分可能被缓冲然后只有在连接完成或是缓冲区已满时才被发送而这有可能会带来比预期要高的延迟。   使用HTTP长轮询的Comet   长轮询long polling模式涉及了打开连接的技术。连接由服务器端保持着打开的状态只要一有事件发生响应就会被提交然后连接关闭。接下来。一个新的长轮询连接就会被正在等待新事件到达的客户端重新打开。   你可以使用script标签或是单纯的XMLHttpRequest对象来实现HTTP长轮询。   script标签   正如iframe一样其目标是把script标签附加到页面上以让脚本执行。服务器端则会挂起连接直到有事件发生接着把脚本内容发送回浏览器然后重新打开另一个script标签来获取下一个事件。   1. 优点因为是基于HTML标签的所有这一技术非常容易实现且可跨域工作缺省情况下XMLHttpRequest不允许向其他域或是子域发送请求。   2. 缺点类似于iframe技术错误处理缺失你不能获得连接的状态或是有干涉连接的能力。   XMLHttpRequest长轮询   第二种也是一种推荐的实现Comet的做法是打开一个到服务器端的Ajax请求然后等待响应。服务器端需要一些特定的功能来允许请求被挂起只要一 有事件发生服务器端就会在挂起的请求中送回响应并关闭该请求完全就像是你关闭了servlet响应的输出流。然后客户端就会使用这一响应并打开一个新 的到服务器端的长生存期的Ajax请求如清单9所示   清单9. 设置长轮询请求的JavaScript代码示例 function long_polling() {  $.getJSON(ajax, function(events) {    processEvents(events);    long_polling();  });}long_polling();   在后端代码也是使用Servlet 3 API来挂起请求正如HTTP流的做法一样但你不需要所有的多部分处理代码清单10给出了一个例子。   清单10. 挂起一个长轮询Ajax请求 protected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {  AsyncContext asyncContext  req.startAsync();  asyncContext.setTimeout(0);  asyncContexts.offer(asyncContext);}   在接收到事件时只是取出所有的挂起请求并完成它们如清单11所示   清单11. 在有事件发生时完成长轮询Ajax请求 while (!asyncContexts.isEmpty()) {  AsyncContext asyncContext  asyncContexts.poll();  HttpServletResponse peer  (HttpServletResponse)  asyncContext.getResponse();  peer.getWriter().write(    new JSONArray().put(At   new Date()).toString());  peer.setStatus(HttpServletResponse.SC_OK);  peer.setContentType(application/json);  asyncContext.complete();}   在附带的下载源文件中comet-long-polling文件夹包含了一个长轮询示例web应用你可以使用 mvn jetty:run 命令来运行它。   1. 优点客户端很容易实现良好的错误处理系统和超时管理。这一可靠的技术还允许在与服务器端的连接之间有一个往返即使连接是非持久的当你的应用有许多的 客户端时这是一件好事。它可用在所有的浏览器上你只需要确保所用的XMLHttpRequest对象发送到的简单的Ajax请求就可以了。   2. 缺点相比于其他技术来说不存在什么重要的缺点像所有我们已经讨论过的技术一样该方法依然依赖于无状态的HTTP连接其要求服务器端有特殊的功能来临时挂起连接。   建议   因为所有现代的浏览器都支持跨域资源共享Cross-Origin Resource ShareCORS规范该规范允许XHR执行跨域请求因此基于脚本的和基于iframe的技术已成为了一种过时的需要。   把Comet做为反向Ajax的实现和使用的最好方式是通过XMLHttpRequest对象该做法提供了一个真正的连接句柄和错误处理。考虑到不 是所有的浏览器都支持multi-part标志且多部分流可能会遇到缓冲问题因此建议你选择经由HTTP长轮询使用XMLHttpRequest对象 在服务器端挂起的一个简单的Ajax请求的Comet模式所有支持Ajax的浏览器也都支持该种做法。   结论   本文提供的是反向Ajax技术的一个入门级介绍文章探索了实现反向Ajax通信的不同方法并说明了每种实现的优势和弊端。你的具体情况和应用需求 将会影响到你对最合适方法的选择。不过一般来说如果你想要在低延迟通信、超时和错误检测、简易性以及所有浏览器和平台的良好支持这几方面有一个最好的 折中的话那就选择使用了Ajax长轮询请求的Comet。   这一文章系列探讨了如何使用反向AjaxReverse Ajax技术来开发事件驱动的web应用第1部分内容介绍了实现反向Ajax通信的几种不同方式轮询polling、捎带piggyback以及使用了长轮询long-polling和流streaming的Comet。在本文中我们学习一种新的实现反向Ajax的技术使用WebSocket一个新的HTML5 API。WebSocket可由浏览器厂商来做本地化实现或是通过把调用委托给隐藏的被称为FlashSocket的Flash组件这种桥接手段来实现。本文还讨论了反向Ajax技术带来的一些服务器端约束。   前言   时至今日用户期待的是可通过web访问快速、动态的应用。这一文章系列展示了如何使用反向AjaxReverse Ajax技术来开发事件驱动的web应用。该系列的第1部分介绍了反向Ajax、轮询polling、流streaming、Comet和长轮询long polling。你已经了解了Comet是如何使用HTTP长轮询的这是可靠地实现反向Ajax的最好方式因为现有的所有浏览器都提供支持。   在本文中我们将学习如何使用WebSocket来实现反向Ajax。代码例子被用来帮助说明WebSocket、FlashSocket、服务器端约束、请求作用域request-scoped服务以及暂停长生存期请求等你可以下载本文中用到的这些源代码。   前提条件   理想情况下要充分体会本文的话你应该对JavaScrpit和Java有一定的了解。本文中创建的例子是使用Google Guice来构建的这是一个使用Java编写的依赖注入框架。若要读懂文中所谈内容你应该要熟悉诸如Guice、Spring或是Pico一类的依赖注入框架的概念。   若要运行本文中的例子你还需要最新版本的Maven和JDK参见参考资料。   WebSocket   在HTML5中出现的WebSocket是一种比Comet还要新的反向Ajax技术WebSocket启用了双向的全双工通信信道许多浏览器Firefox、Google Chrome和Safari都已对此做了支持。连接是通过一个被称为WebSocket握手的HTTP请求打开的其用到了一些特殊的报头。连接会保持在活动状态你可以使用JavaScript来写入和接收数据就像是在使用一个原始的TCP套接口一样。   WebSocket URL的起始输入是ws://或是wss://在SSL上。   图1中的时间线说明了使用WebSocket的通信。一个带有特定报头的HTTP握手被发送到了服务器端接着在服务器端或是客户端就可以通过JavaScript来使用某种套接口socket了这一套接口可被用来通过事件句柄异步地接收数据。   图1. 使用WebSocket的反向Ajax   本文可下载的源代码中有一个WebSocket例子在运行该例子时你应该会看到类似清单1的输出。其说明了客户端的事件是如何发生的以及如何会立即在客户端显示出来。当客户端发送一些数据时服务器端回应客户端的发送行为。   清单1. JavaScript中的WebSocket例子 [client] WebSocket connection opened[server] 1 events[event] ClientID 0[server] 1 events[event] At Fri Jun 1721:12:01 EDT 2011[server] 1 events[event] From 0 : qqq[server] 1 events[event] At Fri Jun 1721:12:05 EDT 2011[server] 1 events[event] From 0 : vv   通常情况下在JavaScript中你会如清单2所说明的那样来使用WebSocket如果你的浏览器支持它的话。   清单2. JavaScript客户端例子 var ws  new WebSocket(ws://127.0.0.1:8080/async);ws.onopen  function() {    // 连接被打开时调用};ws.onerror  function(e) {    // 在出现错误时调用例如在连接断掉时};ws.onclose  function() {    // 在连接被关闭时调用};ws.onmessage  function(msg) {    // 在服务器端向客户端发送消息时调用    // msg.data包含了消息};// 这里是如何给服务器端发送一些数据ws.send(some data);// 关闭套接口ws.close();   发送和接收的数据可以是任意类型的WebSocket可被看成是TCP套接口因此这取决于客户端和服务器端知道要来回发送的数据是哪种类型的。这里的例子发送的是JSON串。   在JavaScript WebSocket对象被创建后如果在浏览器的控制台或是Firebug中仔细看一下HTTP请求的话你应该会看到WebSocket特有的报头。清单3给出了一个例子。   清单3. HTTP请求和相应报头示例 Request URL:ws://127.0.0.1:8080/asyncRequest Method:GETStatus Code:101 WebSocket Protocol HandshakeRequest HeadersConnection:UpgradeHost:127.0.0.1:8080Origin:http://localhost:8080Sec-WebSocket-Key1:1 1~ 33188Yd]r8dp W75qSec-WebSocket-Key2:17; 229 *043M 8Upgrade:WebSocket(Key3):B4:BB:20:37:45:3F:BC:C7Response HeadersConnection:UpgradeSec-WebSocket-Location:ws://127.0.0.1:8080/asyncSec-WebSocket-Origin:http://localhost:8080Upgrade:WebSocket(Challenge Response):AC:23:A5:7E:5D:E5:04:6A:B5:F8:CC:E7:AB:6D:1A:39   WebSocket握手使用所有的这些报头来验证并设置一个长生存期的连接WebSocket的JavaScript对象还包含了两个有用的属性   ws.url返回WebSocket服务器的URL  ws.readyState返回当前连接状态的值  1. CONNECTING 0  2. OPEN 1  3. CLOSED 2   服务器端对WebSocket的处理要稍加复杂一些现在还没有某个Java规范以一种标准的方式来支持WebSocket。要使用web容器例如Tomcat或是Jetty的WebSocket功能的话你得把应用代码和容器特定的库紧密耦合在一起才能访问WebSocket的功能。   示例代码的websocket文件夹中的例子使用的是Jetty的WebSocket API因为我们使用的是Jetty容器。清单4 给出了WebSocket的处理程序。本系列的第3部分会使用不同的后端WebSocket API。   清单4. Jetty容器的WebSocket处理程序 public final class ReverseAjaxServlet extends WebSocketServlet {  Override  protected WebSocket doWebSocketConnect(HttpServletRequest request,String protocol) {    return [...]  }}   就Jetty来说有几种处理WebSocket握手的方式比较容易的一种方式是子类化Jetty的WebSocketServlet并实现doWebSocketConnect方法。该方法要求你返回Jetty的WebSocket接口的一个实例你必须要实现该接口并返回代表了WebSocket连接的某种端点endpoint。清单5提供了一个例子。   清单5. WebSocket实现示例 class Endpoint implements WebSocket {Outbound outbound;Overridepublicvoid onConnect(Outbound outbound) {  this.outbound  outbound;}Overridepublicvoid onMessage(byte opcode, String data) {  // 在接收到消息时调用  // 你通常用到的就是这一方法}Overridepublicvoid onFragment(boolean more, byte opcode,byte[] data, int offset, int length) {  // 在完成一段内容时onMessage被调用  // 通常不在这一方法中写入东西}Overridepublicvoid onMessage(byte opcode, byte[] data,int offset, int length) {  onMessage(opcode, new String(data, offset, length));}Overridepublicvoid onDisconnect() {  outbound null;}}   若要向客户端发送消息的话你要向outbound中写入消息如果清单6所示   清单6. 发送消息给客户端 if (outbound ! null  outbound.isOpen()) {  outbound.sendMessage(Hello World !);}   要断开并关闭到客户端的WebSocket连接的话使用outbound.disconnect()。   WebSocket是一种实现无延迟双向通信的非常强大的方法Firefox、Google Chrome、Opera和其他的现代浏览器都支持这种做法。根据jWebSocket网站的说法   1. Chrome从4.0.249版本开始包含本地化的WebSocket。  2. Safari 5.x包含了本地化的WebSocket。  3. Firefox 3.7a6和4.0b1包含了本地化的WebSocket。  4. Opera从10.7.9.67开始包含了本地化的WebSocket。   欲了解更多关于jWebSocket方面的内容请查阅参考资料。   优点   WebSocket功能强大、双向、低延迟且易于处理错误其不会像Comet长轮询那样有许多的连接也没有Comet流所具有的一些缺点。它的API也很容易使用无需另外的层就可以直接使用而Comet则需要一个很好的库来处理重连接、超时、Ajax请求、确认以及选择不同的传输Ajax长轮询和jsonp轮询。   缺点   WebSocket的缺点有这些   1. 是一个来自HTML5的新规范还没有被所有的浏览器支持。   2. 没有请求作用域request scope因为WebSocket是一个TCP套接口而不是一个HTTP请求有作用域的请求服务比如说Hibernate的SessionInViewFilter就不太容易使用。Hibernate是一个持久性框架其在HTTP请求的外围提供了一个过滤器。在请求开始时其在请求线程中设定了一个上下文包括事务和JDBC连接边界在请求结束时过滤器销毁这一上下文。   FlashSocket   对于不支持WebSocket的浏览器来说有些库能够回退到FlashSocket经由Flash的套接口上。这些库通常会提供同样的官方WebSocket API但他们是通过把调用委托给一个包含在网站中的隐藏的Flash组件来实现的。   优点   FlashSocket透明地提供了WebSocket的功能即使是在不支持HTML5 WebSocket的浏览器上也是如此。   缺点   FlashSocket有着下面的这些缺点   1. 其需要安装Flash插件通常情况下所有浏览器都会有该插件。   2. 其要求防火墙的843端口是打开的这样Flash组件才能发出HTTP请求来检索包含了域授权的策略文件。如果843端口是不可到达的话则库应该有回退动作或是给出一个错误所有的这些处理都需要一些时间最多3秒这取决于库而这会降低网站的速度。   3. 如果客户端处在某个代理服务器的后面的话到端口843的连接可能会被拒绝。   WebSocketJS项目提供了一种桥接方式其要求一个至少是10版本的Flash来为Firefox 3、Inernet Explorer 8和Internet Explorer 9提供WebSocket支持。   建议   相比于CometWebSocket带来了更多的好处。在日常开发中客户端支持的WebSocket速度更快且产生较少的请求从而消耗更少的带宽。不过由于并非所有的浏览器都支持WebSocket因此对于Reverse Ajax库来说最好的选择就是能够检测对WebSocket的支持并且如果不支持WebSocket的话还能够回退到Comet长轮询上。   由于这两种技术需要从所有浏览器中获得最好的做法并保持兼容性因此我的建议是使用一个客户端的JavaScript库该库在这些技术之上提供一个抽象层。本系列的第3和第4部分内容会探讨一些库第5部分则是说明它们的应用。在服务器端正如下一节内容讨论的那样事情则会稍加复杂一些。   服务器端的反向Ajax约束   现在你对客户端可用的反向Ajax解决方案已经有了一个概观让我们再来看看服务器端的反向Ajax解决方案。到目前为止例子使用的都还主要是客户端的JavaScript代码。在服务器端要接受反向Ajax连接的话相比你所熟悉的短HTTP请求某些技术需要特定的功能来处理长生存期的连接。为了得到更好的伸缩性应该要使用一种新的线程模型该模型需要Java中的某个特定API来暂停请求。还有就WebSocket来说你必须要正确地管理应用中用到的服务的作用域。   线程和非阻塞I/O   通常情况下web服务器会把一个线程或是一个进程与每个传入的HTTP连接关联起来。这一连接可以是持久的保持活动这样多个请求就可以通过这同一个连接进行了。在本文的例子中Apache web服务器可以配置成mpm_fork或是mpm_worker模式来改变这一行为。Java web服务器应用服务器也包括在内——这是同一回事通常会为每个传入的连接使用单独的一个线程。   产生一个新的线程会带来内存的消耗和资源的浪费因为其并不保证产生的线程会被用到。连接可能会建立起来但是没有来自客户端或是服务器端的数据在发送。不管这一线程是否被用到其都会消耗用于调度和上下文切换的内存和CPU资源。而且在使用线程模式来配置服务器时你通常需要配置一个线程池设定处理传入连接的线程的最大数目。如果该值配置不当值太小的话你最终就会遭遇线程饥饿问题请求就会一直处于等待状态直到有线程可用来处理它们在达到最大并发连接时响应时间就会下降。另一方面配置一个高值则可会导致内存不足的异常产生过多线程会消耗尽JVM的所有可用的堆导致服务器崩溃。   Java最近引入一个新的I/O API其被称为非阻塞式的I/O。这一API使用一个选择器来避免每次有新的HTTP连接在服务器端建立时都要绑定一个线程的做法当有数据到来时就会有一个事件被接收接着某个线程就被分配来处理该请求。因此这种做法被称为每个请求一个线程thread-per-request模式。其允许web服务器比如说WebSphere和Jetty等使用固定数量的线程来容纳并处理越来越多的用户连接。在相同硬件配置的情况下在这一模式下运行的web服务器的伸缩性要比运行在每个连接一个线程thread-per-connection模型下的好得多。   在Philip McCarthyComet and Reverse Ajax的作者的博客中关于这两种线程模式的可伸缩性有一个很有意思的衡量基准参见参考资料中的链接。在图2中你会发现同样的模式在有太多连接时线程模式会停止工作。   图2. 线程模式的衡量基准   每个连接一个线程模式图2中的Threads通常会有一个更好的响应时间因为所有的线程都已启动、准备好且是等待中但在连接的数目过高时其会停止提供服务。在每个请求一个线程模式图2中的Continuations中线程被用来为到达的请求提供服务连接则是通过一个NIO选择器来处理。响应时间可能会较慢一些但线程会回收再用因此该方案在大容量连接方面有着更好的伸缩性。   想要了解线程在幕后是如何工作的话可以把一个LEGO™积木块想象成是选择器每次传入的连接到达这一LEGO积木块时其由一个管脚来标识。LEGO积木块/选择器有着与连接数一样多的管脚一样多的键。那么只需要一个线程来等待新事件的发生然后在这些管脚上遍历就可以了。当有事情发生时选择器线程从发生的事件中检索出键值然后就可以使用一个线程来为传入的请求提供服务。   “Rox Java NIO Tutorial”这一教程有很好的使用Java中的NIO的例子参见参考资料。   有请求作用域的服务   许多框架都提供了服务或是过滤器filter来处理到达servlet的web请求例如某个过滤器会   1. 把JDBC连接绑定到某个请求线程上这样整个请求就只用到一个连接。   2. 在请求结束时提交所做的改变。   另一个例子是Google Guice一个依赖注入库的Guice Servlet扩展。类似于SpringGuice可把服务绑定在请求的作用域内一个实例至多只会为每个新请求创建一次参阅参考资料获得更多信息。   通常的做法包括了使用用户id来把从储存库中检索出来的用户对象缓存在请求中用户id则是取自集群化的HTTP会话。在Google Guice中你可能会有类似清单7中给出的代码。   清单7. 请求作用域的绑定 ProvidesRequestScopedMember member(AuthManager authManager,MemberRepository memberRepository) {  return memberRepository.findById(authManager.getCurrentUserId());}   当某个member被注入到类中时Guice会尝试这从请求中获取该对象如果没有找到的话它就会执行储存库调用并把结果放在请求中。   请求作用域可与除了WebSocket之外的其他任何的反向Ajax解决方案一起使用任何其他的依赖于HTTP请求的解决方案无论是短的还是长的生存期的都可以每个请求都会通过servlet分发系统过滤器都会被执行。在完成一个暂停的长生存其HTTP请求时你会在这一系列的后继部分中了解到还有另一种做法可让请求再次通过过滤器链。   对于WebSocket来说数据直接到达onMessage回调函数上就像是在TCP套接口中的情况那样。不存在任何的HTTP请求送达这一数据故也不存在获取或是存放作用域对象的请求上下文。因此在onMessage回调中使用需要作用域对象的服务就会失败。可下载源代码中的guice-and-websocket例子说明了如何绕过这一限制以便仍然可在onMessage回调中使用请求作用域对象。当你运行这一例子并在网页上点击每个按钮来测试一个Ajax调用有请求作用域的、一个WebSocket调用和一个使用了模拟请求作用域的WebSocket调用时你会得到图3所示的输出。   图3. 使用了请求作用域服务的WebSocket处理程序   在使用下面任一种技术时你可能都会遇到这些问题   1. Spring   2. Hibernate   3. 任何其他需要请求作用域或是每一请求模型的框架比如说OpenSessionInViewFilter。   4. 任何在过滤器的内部使用ThreadLocal这一设施来指定变量的作用域为请求线程并在以后访问这些变量的系统。   Guice有一个优雅的解决方案如清单8所示   清单8. 在WebSocket的onMessage回调中模拟一个请求作用域 // 在调用doWebSocketMethod时// 保存到请求的引用HttpServletRequest request  [...]Map, Object bindings new HashMap, Object();// 我有一个服务需要一个请求来获取会话// 因此我提供一个请求但你可以提供任何其他// 可能需要的绑定bindings.put(Key.get(HttpServletRequest.class), request);ServletScopes.scopeRequest(new Callable() {  Override  public Object call() throws Exception {  // 调用你的储存库或是任何用到作用域对象的服务    outbound.sendMessage([...]);    return null;  }}, bindings).call();   暂停长生存期请求   若使用Comet的话还有另一障碍存在那就是服务器端如何在不影响性能的情况下暂停一个长生存期请求然后在服务器端事件到来时尽可能快地恢复并完成请求呢   很显然你不能简单地让请求和响应停在那里这会引发线程饥饿和高内存消耗。暂停非阻塞式的I/O中的一个长生存期请求在Java中这需要一个特有的API。Servlet 3.0规范提供了这样的一个API参见本系列的第1部分内容。清单9给出了一个例子。   清单9. 使用Servlet 3.0来定义一个异步的servlet ?xml version1.0 encodingUTF-8?web-app version3.0 xmlnshttp://java.sun.com/xml/ns/javaeexmlns:j2eehttp://java.sun.com/xml/ns/javaeexmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3.0.xsdservletservlet-nameevents/servlet-nameservlet-classReverseAjaxServlet/servlet-classasync-supportedtrue/async-supported/servletservlet-mappingservlet-nameevents/servlet-nameurl-pattern/ajax/url-pattern/servlet-mapping/web-app   在定义了一个异步的servlet之后你就可以使用Servlet 3.0 API来挂起和恢复一个请求如清单10所示   清单10. 挂起和恢复一个请求 AsyncContext asyncContext  req.startAsync();// 把asyncContext的引用保存在某处// 然后在需要的时候在另一个线程中你可以恢复并完成HttpServletResponse req (HttpServletResponse) asyncContext.getResponse();req.getWriter().write(data);req.setContentType([...]);asyncContext.complete();   在Servlet 3.0之前每个容器都有着且现在仍有着自己的机制。Jetty的延续continuation就是一个很有名的例子Java中的许多反向Ajax库都依赖于Jetty的continuation。其并非什么精彩绝伦的做法也不需要你的应用运行在Jetty容器上。该API的聪明之处在于其能够检测出你正在运行的容器如果是运行在另一个容器上比如说Tomcat或是Grizzly那么如果Servlet 3.0 API可用的话就回退到Servlet 3.0 API上。这对于Comet来说没有问题但如果你想要利用WebSocket的优势的话目前别无选择只能使用容器特有的功能。   Servlet 3.0规范还没有发布但许多容器都已经实现了这一API因为这也是实施反向Ajax的一种标准做法。   结束语   WebSocket尽管存在一些不足之处但却是一个功能非常强大的反向Ajax解决方案。其目前还未在所有浏览器上实现且如果没有反向Ajax库的帮助的话在Java服务器端并不容易使用。因为你使用的不是标准的请求-响应风格所有你不能依赖过滤器链的作用域执行。Comet和WebSocket需要服务器端的容器特定功能因此在使用新出的容器时你需要注意一下它可能没有做这方面的扩充。   请继续关注这一系列的第3部分该部分内容将探讨用于Comet和WebSocket的不同的服务器端API你还可了解到Atomsphere这是一个反向Ajax框架。   下载   描述        名称         大小   下载方法   文章的源代码   reverse_ajaxpt2_source.zip 14KB   HTTP   参考资料   1. “Start using HTML5 WebSockets today”Nettuts重温在PHP中如何运行一个WebSocket服务器并考虑如何构建一个客户端来通过WebSocket协议发送和接收消息。   2. “The WebSocket API”W3C, July 2011这一规范定义的API使得网页能够使用WebSocket协议来和远程主机进行双向通信。   3. jWebSocket支持的浏览器了解jWebSocket和Flash套接口桥所支持浏览器的各方面信息。   4. 了解更多关于Servlet 3.0对异步处理的支持方面的内容。   5. Philip McCarthy的博客上的文章Comet Java: Threaded Vs Nonblocking I/O中有着更多的内容。   6. The Rox Java NIO Tutorial这一教程收集了作者使用Java NIO库的一些经验以及几十条的诀窍、技巧、建议和充斥着互联网的告诫做法。   7. 在维基百科上了解这些内容   7.1 Ajax  7.2 Reverse Ajax  7.3 Comet  7.4 WebSockets   8. “Exploring Reverse AJAX”Google Maps .Net Control博客2006年8月获得一些关于反向Ajax技术的介绍说明。   9. “Cross-domain communications with JSONP, Part 1: Combine JSONP and jQuery to quickly build powerful mashups”developerWorks, February 2009了解如何把不起眼的跨域调用技术JSONP和一个灵活的JavaScript库JQuery结合在一起以令人惊讶的速度构建出一些功能强大的聚合应用。   10. “Cross-Origin Resource Sharing (CORS)”规范W3C, July 2010了解更多关于这一机制的内容该机制允许XHR执行跨域请求。   11. “Build Ajax applications with Ext JS”developerWorks, July 2008对大大增强了JavaScript开发的这一框架有一个大概的了解。   12. “Compare JavaScript frameworks”developerWorks, February 2010对极大地增强了JavaScript开发的那些框架有一个整体的了解。   13. “Mastering Ajax, Part 2: Make asynchronous requests with JavaScript and Ajax”developerWorks, January 2006学习如何使用Ajax和XMLHttpRequest对象来创建一种永不会让用户等待服务器响应的请求/响应模型。   14. “Create Ajax applications for the mobile Web”developerWorks, March 2010了解如何使用Ajax构建跨浏览器的智能手机Web应用。   15. “Where and when to use Ajax in your applications”developerWorks, February 2008了解如何使用Ajax来改进网站同时避免糟糕的用户体验。   16. “Improve the performance of Web 2.0 applications“developerWorks, December 2009探讨不同的浏览器端缓存机制。   17. “Introducing JSON”JSON.org获得对JSON语法的一个入门介绍。   18. developerWorks Web development zone获得各种谈论基于Web的解决方案的文章。   19. developerWorks podcasts收听各种与软件开发者进行的有趣的访谈和讨论。   20. developerWorks technical events and webcasts随时关注developerWorks的技术事件和webcast的进展。   获取产品和技术   1. WebSocketJSWebSocket Flash Bridge获取这一由Flash支持的HTML5 WebSocket实现。   2. Google Guice获取Google Guice一个Java 5及以上版本的轻量级的依赖注入框架。   3. Jetty获取Jetty一个web服务器和javax.servlet容器外带对WebSocket的支持。   4. Apache Maven获取Maven一个软件项目管理和包容工具。   5. Java Development Kit, Version 6获得Java平台标准版Java Platform, Standard EditionJava SE该平台允许你在台式机和服务器上以及在当今要求苛刻的嵌入式环境上开发和部署Java应用。   6. 免费试用IBM软件下载使用版登录在线试用在沙箱环境中使用产品或是通过云来访问有超过100种IBM产品试用版选择。   讨论   1. 现在就创建你的developerWorks个人资料并设置一个关于Reverse Ajax的观看列表。与developerWorks社区建立联系并保持联系。   2. 找到其他在web开发方面感兴趣的developerWorks成员。   3. 分享你的知识加入一个关注web专题的developerWorks组。   4. Roland Barcia在他的博客中谈论Web 2.0和中间件。   5. 关注developerWork成员的shared bookmarks on web topics。   6. 快速获得答案访问Web 2.0 Apps论坛。   7. 快速获得答案访问Ajax论坛。  转载于:https://www.cnblogs.com/student-programmer/p/6743352.html
http://wiki.neutronadmin.com/news/306078/

相关文章:

  • 网站标题优化怎么做天津网站建设公司
  • 四川省城乡建设部网站首页长春生物新冠疫苗
  • 北京高端网站开发网上商店是指
  • 网站开发简历项目门户网站建设方案ppt 百度文库
  • wordpress怎么和手机连接数据库北京网站优化方案
  • 啊里云服务器怎么做网站网站建设小工具
  • 兰州网站排名哪家公司好好的建设网站公司
  • 山东济宁做网站的公司有哪些交互式网站备案
  • 西宁微网站建设多少钱新闻发稿计划怎么写
  • 期货模拟网站开发汉中城乡建设网站首页
  • 怎么自己做微网站赣州网站制作找哪家好
  • 网站下载地址wordpress影视主题带采集
  • 品牌网站模板怎么用自己的主机做网站服务器
  • 做网站美工要学什么软件群晖中使用wordpress
  • 网站二级菜单是什么意思网页设计作品论文
  • 网站开发技术代码哈尔滨建站软件
  • 上海电商网站设计百度 wordpress react
  • ppt成品免费下载的网站深圳找工作哪个网站好
  • 便宜模板网站建设wordpress 教程
  • 阿里云服务器创建多个网站建设平台类网站需要多少钱
  • 动漫网站logo邯郸网站设计怎么开发
  • 网站开发管理工具有哪些做百度网站的公司哪家好
  • 网站建设柒首先金手指8快速迁移网站
  • access如何与网站连接数据库网站开发如何设置背景图片
  • 郴州市建设局网站节能科2345电视剧网站免费
  • 做网站需要工商证吗部门网站建设的工作领导小组
  • 网站运营分析centos wordpress ftp
  • 自动生成图片的网站蒙阴蜜桃
  • 关于电子商务网站建设的现状iis 7.5 网站
  • 四川定制网站建设网站怎么搭建