即时Web通信在一些对数据实时性要求特别严格的应用中十分重要,如监控系统、报价系统、股票交易系统和即时在线聊天应用等,由于http协议设计当初是为了服务器端响应客户端的请求而设计的,只能在客户端主动发送请求后进行处理然后返回结果。为了实现上述各种即时应用的功能,出现了一系列“Hack”的手段来模拟实现服务器端主动推送信息的功能,也就是模拟了服务器和客户端直接全双工的通信。这样主要考虑的是如下问题:

  • 客户端如何接收、处理信息,是否需要使用套接口或是使用远程调用。客户端呈现给用户的是 HTML 页面还是 Java applet 或 Flash 窗口。如果使用套接口和远程调用,怎么和 JavaScript 结合修改 HTML 的显示。
  • 客户与服务器端通信的信息格式,采取怎样的出错处理机制。
  • 客户端是否需要支持不同类型的浏览器如 IE、Firefox,是否需要同时支持 Windows 和 Linux 平台。

与此同时,HTML5中websocket的出现作为新一代实现真正服务器与客户端全双工连接的方式,是目前以及今后开发实时Web应用的主要实现方法。

一、基于客户端套接口的实现

1、Java Applet

客户端浏览器安装java插件后,通过将java applet嵌入到html页面中,通过java.net.Socekt或者java.net.DatagramSocekt或者java.net.MulticastSocket建立与服务器端的套接字接口连接,这是建立的原始的TCP套接字来实现服务器主动推送消息。其不足指出是客户端收到服务器端返回的信息后无法通过javascript更新html页面的内容。这种方法是1996年最早在Netscape2.0浏览器中实现的。

2、Flash XML Socket

客户端浏览器安装Flash插件后,利用Flash提供的XMLSocket类来建立socket连接。同时javascript与Flash联系紧密,在javascript中可以直接调用Flash程序提供的接口。

具体方法是在页面嵌入使用XMLSocket类的Flash程序,javascript通过调用Flash提供的套接口接口与服务器端套接口通信,javascript收到以XML格式返回的信息后可以很容易控制和修改hml页面的内容,因此这种方式在目前的很多应用中依然广泛使用。但是使用套接口需要设置通信端口,可能受到防火墙或者代理服务器的端口限制,同时必须要安装Flash插件才能使用。

二、Comet模型

Comet是一种实现Web推送的编程模型,能使服务器主动将变化的数据发送到客户端而无需客户端发送请求。在2001年最早使用了建立两个http socket连接的方式来实现,是基于J2SE的一个web服务器。在2006年Alex Russell在其个人博客中发表了comet这个概念,此时使用Ajax方式来实现。Comet翻译为中文就是“彗星”,用在这里就是指客户端与服务器端建立连接后,会像彗星托着长长的尾巴一样一直保持连接,从而就可以实现服务器主动发送数据到客户端的即时要求。总结起来,基于comet模型的实现方式概括为以下两种:Streaming和Polling。

1、Streaming

使用基于iframe的html页面标记,通过在html页面嵌入一个隐藏帧,将其的src属性设置为对一个长连接的请求,这样服务器端就可以不断往客户端输入数据。

服务器端返回的数据不是具体在页面显示的html文档内容,而是返回对客户端javascript函数调用的javascript代码,类似于:

  1. <script type="text/javascript">js_func("data from server");</script>

ifream收到这样的script代码后写入到页面,浏览器的javascript引擎执行这些javascript代码,就达到了服务器推送的目的。其中服务器端代码需要做特殊处理,使用一个无限循环保持这个连接,每次循环flush内容,然后sleep一段时间后进入下一次循环。

这种方式的优点是在绝大多数浏览器都支持,不足在于缺乏一种有效的错误处理机制,还有就是跟踪推送中间过程的不同状态基本是不可能的,同时必须配合非阻塞的服务器才能使用,否则多人访问同一页面将服务器IO占满之后就不能访问了。

2、Polling

自从有了Ajax以后,通过使用javascript代码调用XMLHttpRequest对象在客户端发送http请求就得以实现。与基于插件形式实现的不同的是:

  • 服务器端会阻塞请求直到有数据传递或超时才返回。
  • 客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
  • 当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。
Polling就是一种编程模式,通过客户端javascript不断发送请求询问服务器是否有变更的数据,每次发送询问的请求之后,可以选择关闭连接,这就是一般的轮询,如果保持连接不关闭就是长轮询。这种方式,请求异步发出,无需安装插件,同时各浏览器提供都支持。
普通轮询:客户端发送利用javascript的setInteval函数每隔一段时间就想服务器发送一个Ajax请求来取回服务器的数据,这种方式服务器端代码不需做特殊处理。如每隔一分钟检查一次Cookie是否过期。
长连接:客户端代码发送一个Ajax请求后,在onreadystatechange处理函数中判断readyState为3的时候就接收服务器的数据,并记录下此时接收数据的位置,使用substring函数取得当前数据后现实到DOM中。此时服务器端代码需要做特殊处理,服务器端php脚本中使用一个无限循环,每一次循环使用flush输出结果后sleep一段时间然后进行下一次循环输出。这样就将所有负担交给了服务器端。需要一直保持这个到客户端的连接。服务器代码与基于iframe的方案相同。这种做法的缺点就是IE不能在readyState为3的时候处理返回的数据,因此不兼容IE。
长轮询:目前除了Websocket之外应用最广泛的解决方案,iframe和长连接都是一直保持连接,但长轮询则是发送一个长时间等待的请求后,当服务器又数据返回时就返回数据并断掉连接,客户端接收到数据后再次发送一个长时间连接的请求。这个方案也需要服务器端的特殊处理来配合。

三、Websocket

HTML5提供了Websocket,定义了一个全双工通信的信道,这不仅仅是对常规HTTP通信的一种增量,同时是一个巨大进步,对即时的、事件驱动的Web程序的实现提供了无线的开发空间。

使用轮询时,由于实时数据不可测,因此不能避免有不必要的请求,这样在低消息率情况下会有很多无用的连接不断打开和关闭,浪费流量。

使用长轮询时,服务器收到请求后在一段时间保持打开,在时间内服务器收到通知则发送响应,否则当时间到了的时候就终止打开的请求,但是当信息量很大的时候,与轮询相比并没有实质性的性能改善。

使用流解决方案时,浏览器发送请求后服务器会一直保持打开状态,且是无限期或一段时间内都处于打开状态。这样当访问量很大时,每个连接都会消耗服务器很多资源,对服务器端的压力很大。同时由于流任然是封装在http中,期间的防火墙和代理服务器可能对响应消息进行缓冲从而造成消息传递的时延。

同时,只要是基于http请求的凡事都会涉及http请求头和响应头,包含有大量不必要的数据,这样大量耗费了网络带宽,而真正用于传递有效信息的数据可能只有几个字节,得不偿失。同时半双工http基础上模拟全双工需要使用两个连接,一个用于下行数据流,一个用于上行数据流。这样两个连接的协作也会造成大量的资源消耗。

综合上述,websocket的出现就是为了解决上述所有解决方案的不足而设计的。websocket可以实现500:1甚至1000:1的http消息头流量的缩减,同时实现3:1的通信延迟的缩减。同时实现起来简单高效。

以上总结是对整个即时Web通信的概念性总结,个人总觉得对整体有个概念性总结后,就不会在具体实现的时候以致盲目,关于具体实现细节在见另外博文,同时各人实现起来的方式也会有所不同,愿和大家一起交流学习。

即时Web通信总结的更多相关文章

  1. JavaScript之web通信

    web通信,一个特别大的topic,涉及面也是很广的.因最近学习了 javascript 中一些 web 通信知识,在这里总结下.文中应该会有理解错误或者表述不清晰的地方,还望斧正! 一.前言 1. ...

  2. 【转】JavaScript之web通信

    原文转自:http://cloudbbs.org/forum.php?mod=viewthread&tid=28773&page=1&extra=#pid180304 一.前言 ...

  3. Web 通信 之 长连接、长轮询(转)

    Web 通信 之 长连接.长轮询(long polling) 基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强 ...

  4. [转]Web 通信 之 长连接、长轮询(long polling)

    本篇文章转载自Web 通信之长连接.长轮询(longpolling),版权归作者所有. 转者按:随着技术的发展,在HTML5中,可以通过WebSocket技术来完成长连接的开发,虽然如此,本文依然存在 ...

  5. Web 通信 之 长连接、长轮询(long polling)(转载)

    基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强了程序的实时性和交互性. 一.什么是长连接.长轮询? 用通俗易 ...

  6. Web 通信 之 长连接、长轮询(转)

    Web 通信 之 长连接.长轮询(long polling) 基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强 ...

  7. Flask —— 使用Python和OpenShift进行即时Web开发

    最近Packtpub找到了我,让我给他们新出版的关于Flask的书写书评.Flask是一个很流行的Python框架.那本书是Ron DuPlain写的<Flask 即时Web开发>.我决定 ...

  8. Web通信之:长轮询(long-polling)(转)

    Web通信之:长轮询(long-polling) “轮询”是个耐人寻味的词,第一次看到它的时候我就直接理解为“轮流查询”了.但是看到了英文才知道这个是网络通信专业的术语.轮询,其实就是一群人在排队买东 ...

  9. Web通信中的Get、Post方法

    首先我们要了解Tomcat,Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选. ...

随机推荐

  1. android学习日记10--裁剪区域

    裁剪区域 裁剪是画布的一个函数,区域可以是矩形和圆形,也可以通过设置 path 或Region来显示自定义区域,通过不同组合,Android几乎可以支持任意现状的裁剪区域.android.graphi ...

  2. unity3D Socket连接C#server出现unity3D编辑器再次启动连接 unity3D编辑器马上卡死

    unity3D Socket与C#server第一次连接时通讯正常.客服端段关闭后.unity3D编辑器再次启动连接 unity3D编辑器马上卡死 原因是Socket处于异步状态,而异步线程是不受Un ...

  3. com.transfer.www

    package com.transfer.www; import java.io.IOException; import java.io.PrintWriter; import javax.servl ...

  4. MS OFFICE 2010破解版安装

    受人所托发布一个MS OFFICE 2010破解版的傻瓜安装教程,刚好新本本也没有安装,安装过程中截了几个图就搞定了. 安装包: http://www.itopdog.cn/soft/office20 ...

  5. 两个字符串,若为数字则都相加,若有一个不为数字则,输出error

    import java.util.*; /*请设计一个算法能够完成两个用字符串存储的整数进行相加操作,对非法输入则返回“error”: * 用例:123 234 * 输出:357 * 用例123 as ...

  6. android客户端从服务器端获取json数据并解析的实现代码

    今天总结一下android客户端从服务器端获取json数据的实现代码,需要的朋友可以参考下   首先客户端从服务器端获取json数据 1.利用HttpUrlConnection /** * 从指定的U ...

  7. app卡顿问题检测--KMCGeigerCounter

    介绍: KMCGeigerCounter是一个iOS帧速计算器,像盖革计数器那样,当动画丢失一帧时它就记录一次.掉帧通常是不可见的,但是很难区分55fps和60fps之间的不同,而KMCGeigerC ...

  8. c++与c不太相同的一些地方2

    1.一般全局变量放到cpp 文件里面,而不是.h 里面.要不然容易乱套,这个乱几次就好了,先记住这样一种编码规范. 以为大家都引入就比较麻烦,但是实现起来就只有cpp里面才有.毕竟.h是要被包含的文件 ...

  9. [转载][记录]shell 批量修改文件名

    参考了:[新手入门] shell脚本批量修改文件名 4楼回复 我刚好是在vagrant+ubuntu中进行开发,windows手动修改太麻烦. #!/bin/ksh ls *.htm | while ...

  10. linux---基本查找命令

    基本查找命令 一.文件查找命令:find 最大特点:功能强大,可以使用文件的各种属性作为查找条件来查找文件 文件属性:文件权限.文件所有者.文件大小.修改时间.文件类型 语法:find[起始查找目录] ...