反向Ajax:WebSocket

郭晨 软件151 1531610114

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/async
Request Method:GET
Status Code:101 WebSocket Protocol Handshake

Request Headers
Connection:Upgrade
Host:127.0.0.1:8080
Origin:http://localhost:8080
Sec-WebSocket-Key1:1 &1~ 33188Yd]r8dp W75q
Sec-WebSocket-Key2:17; 229 *043M 8
Upgrade:WebSocket
(Key3):B4:BB:20:37:45:3F:BC:C7

Response Headers
Connection:Upgrade
Sec-WebSocket-Location:ws://127.0.0.1:8080/async
Sec-WebSocket-Origin:http://localhost:8080
Upgrade: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;
@Override
publicvoid onConnect(Outbound outbound) {
  this.outbound = outbound;
}
@Override
publicvoid onMessage(byte opcode, String data) {
  // 在接收到消息时调用
  // 你通常用到的就是这一方法
}
@Override
publicvoid onFragment(boolean more, byte opcode,byte[] data, int offset, int length) {
  // 在完成一段内容时,onMessage被调用
  // 通常不在这一方法中写入东西
}
@Override
publicvoid onMessage(byte opcode, byte[] data,int offset, int length) {
  onMessage(opcode, new String(data, offset, length));
}
@Override
publicvoid 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支持。

时间: 2024-08-26 03:34:56

反向Ajax:WebSocket的相关文章

Ajax、反向Ajax和WebSocket 概念

Ajax 异步的JavaScript和XML(Asynchronous JavaScript and XML,Ajax),一种可通过JavaScript来访问的浏览器功能特性,其允许脚本向幕后的网站发送一个HTTP请求而又无需重新加载页面.Ajax的出现已经超过了十年,尽管其名字中包含了XML,但你几乎可以在Ajax请求中传送任何的东西,最常用的数据是JSON,其与JavaScript语法很接近,且消耗更少带宽.清单1给出了这样的一个例子,Ajax请求通过某个地方的邮政编码来检索该地的名称. 清

反向Ajax,第2部分:WebSocket

英文原文:Reverse Ajax, Part 2: WebSockets 前言 时至今日,用户期待的是可通过web访问快速.动态的应用.这一文章系列展示了如何使用反向Ajax(Reverse Ajax)技术来开发事件驱动的web应用.该系列的第1部分介绍了反向Ajax.轮询(polling).流(streaming).Comet和长轮询(long polling).你已经了解了Comet是如何使用HTTP长轮询的,这是可靠地实现反向Ajax的最好方式,因为现有的所有浏览器都提供支持. 在本文中

反向Ajax之Socket.io

1.什么是反向ajax? 传统的ajax的困惑? 新需求--当服务器端数据发生变化时,客户端(浏览器端)如何即时得到通知呢? 找一些实际的案例:客服系统.在线聊天 这类应用,有一个显著的特点: 数据并不是单向的,原来的数据,都是从浏览器端向服务器端发起请求,然后获取数据. 现在的需求发生变化了,有时候,数据是从服务器端 推送 到浏览器端. 前面所有的http请求/响应模型都是基于单向的,包括ajax. 从服务端向浏览器端推送数据的这种ajax应用,称之为反向ajax. 2.常见解决方案   有以

反向Ajax,第5部分:事件驱动的Web开发

英文原文:Reverse Ajax, Part 5: Event-driven web development 前言 这一文章系列展示了如何使用反向Ajax(Reverse Ajax)技术开发事件驱动的web应用,第1部分内容介绍了反向Ajax.轮询(polling).流(streaming).Comet和长轮询(long polling):第2部分内容说明了如何使用WebSocket来实现反向Ajax,并讨论了使用Comet和WebSocket的web服务器的局限性:第3部分内容说明了如果需要

反向Ajax,第1部分:Comet介绍

英文原文:Reverse Ajax, Part 1: Introduction to Comet 在过去的几年中,web开发已经发生了很大的变化.现如今,我们期望的是能够通过web快速.动态地访问应用.在这一新的文章系列中,我们学习如何使用反向Ajax(Reverse Ajax)技术来开发事件驱动的web应用,以此来实现更好的用户体验.客户端的例子使用的是JQuery JavaScript库,在这首篇文章中,我们探索不同的反向Ajax技术,使用可下载的例子来学习使用了流(streaming)方法

反向Ajax,第3部分:Web服务器和Socket.IO

英文原文:Reverse Ajax, Part 3: Web servers and Socket.IO 前言 时至今日,用户期待的是可通过web访问快速.动态的应用.这一文章系列展示了如何使用反向Ajax(Reverse Ajax)技术来开发事件驱动的web应用.系列的第1部分介绍了反向Ajax.轮询(polling).流(streaming).Comet和长轮询(long polling).你已经了解了Comet是如何使用HTTP长轮询的,这是可靠地实现反向Ajax的最好方式,因为现有的所有

反向Ajax,第4部分:Atmosphere和CometD

英文原文:Reverse Ajax, Part 4: Atmosphere and CometD 前言 这一系列文章展示了如何使用反向Ajax技术开发事件驱动的web应用,第1部分内容介绍了反向Ajax(Reverse Ajax).polling(轮询).streaming(流).Comet和长轮询(long polling):第2部分内容介绍了如何使用WebSocket来实现反向Ajax,并讨论了使用Comet和WebSocket的web服务器的局限性:第3部分内容说明的是,如果需要支持多种服

08 comet反向ajax

一:HTTP协议与技久链接+分块传输---->反向ajax 反向ajax又叫comet, server push,服务器推技术. 应用范围: 网页聊天服务器,, 新浪微博在线聊天,google mail 网页聊天,都有用到. 原理: 一般而言, HTTP协议的特点, 连接<->断开. 具体什么时间断开? 服务器响应content-length,收到到指定length长度的内容时,也就断开了. 在http1.1协议中, 允许你不写content-length ,比如要发送的内容长度确实不知

http协议与分块传输,持久连接及反向ajax

web QQ都用过吧,这涉及到哪些技术,有一个就是反向ajax. 反向ajax又叫comet,server push,服务器推技术. 应用范围: 网页聊天服务器,, 新浪微博在线聊天,google mail 网页聊天,都有用到. 原理: 一般而言, HTTP协议的特点, 连接<->断开. 具体什么时间断开? 服务器响应content-length,收到到指定length长度的内容时,也就断开了. 在http1.1协议中, 允许你不写content-length,比如要发送的内容长度确实不知道时