web 服务端与客户端交互

来源:互联网 发布:js utc转换北京时间 编辑:程序博客网 时间:2024/06/07 00:27

Web server to client communication

Technology

 

1.   Traditional solution

 

传统模式的 Web系统以客户端发出请求、服务器端响应的方式工作.

 

       web应用中,客户断若想更新服务端数据,通过向服务端发送HTTP request, 等到服务器做出相应,返回视图并更新客户端。  
 
 缺点:无法生成动态页面

 

1.1.        Server side

       1、最早的解决方案:CGI通用网关接口(一种与外部程序通讯的标准)
         
原理:web服务器调用外部程序,再将返回的结果返回客户端
         CGI
的缺点:每次客户端请求都要在服务器上开启一个进程,这样会大大消耗服务器资源
          
更好的解决方案是:开启服务器进程一次,就处理所有请求


       2
java的解决方案(解决CGI的缺点:其实CGI是现在web服务器的鼻祖):servlet+web容器
          servlet
是一个与平台无关的java接口
         
 理解servlet,是掌握javaweb编程的核心
          sevlet受控于另一个java应用程序,它就是web容器
          servlet+web
容器:为每个请求开启一个线程,线程占用进程的一部分
          sevlet
没有main方法,说明它要被别的类web容器调用

 

1.2.        Client side

Brower, 只能解析html静态文件

 

 
 
HTTP:超文本传输协议(Hypertext Transfer Protocol
 
客户端-----通过socket建立连接-----服务器 客户端-----请求----->服务器
 客户端<-----响应-----服务器 客户端-----断开-----服务器
 
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。
 
HTTP请求信息(浏览器信息)       1、请求行:GET/POST(流的组织(请求)方式) URL(地址+目录版本号       2、请求头:Host:客户端IP和端口         User-Agent:浏览器信息         Accept:客户端能接收的数据类型         Accept-encoding:是否支持压缩的流         Accept-charset:客户端字符编码集       3、空行:分割请求头和消息体       4、消息体:请求的参数

 

HTTP响应信息(服务器信息)
       1
、状态行:HTTP版本  服务器状态(比如:404找不到...) 描述信息
       2
、响应头
        content-text
:服务器发送信息的类型
        date
:发送时间
        server
:服务器类型
       3
、消息体:服务器发送给客户端的页面内容

 

 

 

传统模式的 Web并不能满足很多现实应用的需求,譬如:

 

监控系统:后台硬件热插拔、LED、温度、电压发生变化;

即时通信系统:其它用户登录、发送信息;

即时报价系统:后台数据库内容发生变化;

 

 

 

 

 

 

2.   Current Popular solution

 

 

实时技术解决方案

 

    1. 基于客户端套接口 

1.1.    Flash XMLSocket

  

如果 Web 应用的用户接受应用只有在安装了 Flash 播放器才能正常运行,那么使用 Flash XMLSocket 也是一个可行的方案。

 

这种方案实现的基础是:

 

Flash 提供了 XMLSocket类。

JavaScript Flash的紧密结合:在 JavaScript 可以直接调用 Flash程序提供的接口。

具体实现方法:在 HTML页面中内嵌入一个使用了 XMLSocket 类的 Flash程序。JavaScript 通过调用此 Flash程序提供的套接口接口与服务器端的套接口进行通信。JavaScript在收到服务器端以 XML 格式传送的信息后可以很容易地控制 HTML页面的内容显示。

 

关于如何去构建充当了 JavaScript Flash XMLSocket 桥梁的 Flash程序,以及如何在 JavaScript 里调用 Flash提供的接口,我们可以参考 AFLAXAsynchronous Flash and XML)项目提供的 Socket Demo以及 SocketJS(请参见参考资源)。

 

Javascript Flash的紧密结合,极大增强了客户端的处理能力。从 Flash 播放器 V7.0.19 开始,已经取消了 XMLSocket的端口必须大于 1023 的限制。Linux平台也支持 Flash XMLSocket 方案。但此方案的缺点在于:

 

客户端必须安装 Flash播放器;

因为 XMLSocket没有 HTTP 隧道功能,XMLSocket类不能自动穿过防火墙;

因为是使用套接口,需要设置一个通信端口,防火墙、代理服务器也可能对非 HTTP通道端口进行限制;

不过这种方案在一些网络聊天室,网络互动游戏中已得到广泛使用。

 

 

1.2.     Java Applet 套接口

 

               在客户端使用 Java Applet,通过 java.net.Socket java.net.DatagramSocket java.net.MulticastSocket 建立与服务器端的套接口连接,从而实现“服务器推”。

 

这种方案最大的不足在于 Java applet在收到服务器端返回的信息后,无法通过 JavaScript 去更新 HTML 页面的内容。

 

 

2. 基于 HTTP长连接

        2.1 轮询(long-polling

        2.1.1 Meta 轮询

最简单的解决方案便是定时刷新页面。在HTML文档的头部使用HTMLMETA标签,页面便可以每隔N秒自动reload一次。如果在此期间server端数据发生变化,那么我们可以获得新的内容,否则将得到相同的页面。虽然方法很简单,但是如何设置刷新间隔是让人头疼的大问题。

           2.1.2.  AJAX的长轮询(long-polling)方式

AJAX 的出现使得 JavaScript可以调用 XMLHttpRequest 对象发出 HTTP请求,JavaScript 响应处理函数根据服务器返回的信息对 HTML页面的显示进行更新。使用 AJAX 实现“服务器推”与传统的 AJAX应用不同之处在于:

 

服务器端会阻塞请求直到有数据传递或超时才返回。

客户端 JavaScript响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。

当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。

 

相对于“轮询”(poll),这种长轮询方式也可以称为“拉”(pull)。因为这种方案基于 AJAX,具有以下一些优点:请求异步发出;无须安装插件;IEMozilla FireFox 都支持 AJAX

 

在这种长轮询方式下,客户端是在 XMLHttpRequest readystate 4(即数据传输结束)时调用回调函数,进行信息处理。当 readystate 4 时,数据传输结束,连接已经关闭。Mozilla Firefox提供了对 Streaming AJAX 的支持,即 readystate 3 时(数据仍在传输中),客户端可以读取数据,从而无须关闭连接,就能读取处理服务器端返回的信息。IE readystate 3时,不能读取服务器返回的数据,目前 IE 不支持基于 Streaming AJAX

 

 

2.2    基于 Iframe htmlfile 的流(streaming)方式

 

iframe 是很早就存在的一种 HTML标记,通过在 HTML 页面里嵌入一个隐蔵帧,然后将这个隐蔵帧的 SRC属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。

 

使用 iframe请求一个长连接有一个很明显的不足之处:IEMorzilla Firefox下端的进度栏都会显示加载没有完成,而且 IE 上方的图标会不停的转动,表示加载正在进行。

 

 

  1. 服务端回调(server-side callbacks

 

 

4. 消息(MOM

 

这种解决方案采用一个作为clientapplet,它使用TCP/IP或者无连接的UDP、甚至多播协议来建立与消息中间件server的通讯,然后由server推送消息给client。你可以从例如SoftWirediBusIBMMQSeriesBEAWebLogic Event这些消息产品中直接挑选,或者自己使用基于socketjava.io.ObjectStream定制开发消息软件

 

 

3 Pushlet in comet

 

3.1 Comet 简介o

 

浏览器作为 Web应用的前台,自身的处理功能比较有限。浏览器的发展需要客户端升级软件,同时由于客户端浏览器软件的多样性,在某种意义上,也影响了浏览器新技术的推广。在 Web应用中,浏览器的主要工作是发送请求、解析服务器返回的信息以不同的风格显示。AJAX是浏览器技术发展的成果,通过在浏览器端发送异步请求,提高了单用户操作的响应性。但 Web本质上是一个多用户的系统,对任何用户来说,可以认为服务器是另外一个用户。现有 AJAX技术的发展并不能解决在一个多用户的 Web 应用中,将更新的信息实时传送给客户端,从而用户可能在“过时”的信息下进行操作。而 AJAX的应用又使后台数据更新更加频繁成为可能。

 

 

3.2  Pushlet is framework

 

pushlet原理

Pushlet的基本使用形式是极为简单的。后面的一些示例会说明这一点。  Pushlet基于HTTP流,这种技术常常用在多媒体视频、通讯应用中,比如QuickTime。与装载HTTP页面之后马上关闭HTTP连接的做法相反,Pushlet采用HTTP流方式将新变动的数据主动地推送到client(客户端),再此期间HTTP连接一直保持打开。

 

采用观察者模型

客户端发送请求,订阅感兴趣的事件;服务器端为每个客户端分配一个会话 ID作为标记,事件源会把新产生的事件以多播的方式发送到订阅者的事件队列里。

 

客户端 JavaScript

 

pushlet 提供了基于 AJAX JavaScript 库文件用于实现长轮询方式的“服务器推”;还提供了基于 iframe JavaScript 库文件用于实现流方式的“服务器推”。

 

JavaScript 库做了很多封装工作:

 

定义客户端的通信状态:STATE_ERRORSTATE_ABORTSTATE_NULLSTATE_READYSTATE_JOINEDSTATE_LISTENING

保存服务器分配的会话 ID,在建立连接之后的每次请求中会附上会话 ID表明身份;

提供了 join()leave()subscribe() unsubsribe()listen() API 供页面调用;

提供了处理响应的 JavaScript函数接口 onData()onEvent()

网页可以很方便地使用这两个 JavaScript库文件封装的 API 与服务器进行通信。

 

客户端与服务器端通信信息格式

 

pushlet 定义了一套客户与服务器通信的信息格式,使用 XML格式。定义了客户端发送请求的类型:joinleavesubscribeunsubscribelistenrefresh;以及响应的事件类型:datajoin_acklisten_ackrefreshheartbeaterrorabortsubscribe_ackunsubscribe_ack

 

服务器端事件队列管理

 

pushlet 在服务器端使用 Java Servlet实现,其数据结构的设计框架仍可适用于 PHPC编写的后台客户端。

 

Pushlet 支持客户端自己选择使用流、拉(长轮询)、轮询方式。服务器端根据客户选择的方式在读取事件队列(fetchEvents)时进行不同的处理。“轮询”模式下 fetchEvents()会马上返回。”流“和”拉“模式使用阻塞的方式读事件,如果超时,会发给客户端发送一个没有新信息收到的“heartbeat“事件,如果是“拉”模式,会把“heartbeat”与“refresh”事件一起传给客户端,通知客户端重新发出请求、建立连接。

 

客户服务器之间的会话管理

 

服务端在客户端发送 join请求时,会为客户端分配一个会话 ID,并传给客户端,然后客户端就通过此会话 ID标明身份发出 subscribe listen请求。服务器端会为每个会话维护一个订阅的主题集合、事件队列。

 

服务器端的事件源会把新产生的事件以多播的方式发送到每个会话(即订阅者)的事件队列里。

 

 

 

4. MOM

 

上面三种解决方案在复杂性、安全性、性能、可测量性、浏览器兼容性、防火墙限制上各有优势、劣势。最佳解决方案依赖于你的应用需求。例如,在共享白板应用中,用户需要直接与“状态”交互,那么server端回调或者消息很可能会大显身手。  但在浏览器环境下,除非完全使用applet作为整个client应用,否则把来自于server的更新信息集成到页面中并非易事。如何在applet收到回调或者消息时变更页面相关内容?一个很“痛快”而又“痛苦”的解决方案就是在回调方法中使用AppletContext.showDocument(URL)方法来刷新整个页面。  由于HTML代码可以直接影响页面布局,直接使用来自server的数据更改HTML部分内容不是更好吗?这是web应用的理想方案,在server上内容动态改变时,从用户到server所需的交互是最小化的。作为对上面的解决方案的补充,我开发了Pushlet这种轻量级、瘦客户端的技术,它无需applet或者插件而直接与脚本/HTML集成在一起、使用标准HTTP连接、理论上可以部署到任何支持Java servletserver上。但这并不意味着它将替换对前面解决方案,而是在你的开发“工具箱”中添加另一种选择。作为Java构架者/开发者,你可以自行权衡、选择、决定哪种适合应用的解决方案。