Web端server推送技术原理分析及dwr框架简单的使用
“server推送技术”(ServerPushing)是近期Web技术中最热门的一个流行术语。它是继“Ajax”之后又一个倍受追捧的Web技术。“server推送技术”近期的流行跟“Ajax ”有着密切的关系。
随着 Ajax技术的兴起,让广大开发者重新看到了使用浏览器来替代桌面应用的机会,而且这次机会很大。Ajax将整个页面的刷新变成页面局部的刷新,而且数据的传送是以异步方式进行,这使得网络延迟带来的视觉差异将会消失。
可是,在浏览器中的 Ajax应用中存在一个致命的缺陷无法满足传统桌面系统的需求。那就是“server发起的消息传递”(Server-Initiated Message Delivery)。在非常多的应用其中,server软件须要向client主动发送消息或信息。由于server掌握着系统的主要资源,可以最先获得系统的状态变化和事件的发生。当这些变化发生的时候,server须要主动的向client实时的发送消息。比如股票的变化。在传统的桌面系统这样的需求没有不论什么问题,由于client和server之间通常存在着持久的连接,这个连接可以双向传递各种数据。而基于HTTP协议的 Web应用却不行。
2 client得到通知的方式
图1 传统web 訪问机制
我们知道, Web的訪问机制天生是设计用来 pull数据的,如图 1,也就是仅仅同意 Browser端主动发起请求,server是被动的响应,不同意Server向 Browser发出一个 connection请求,也就是说没有为server向 Browser
push数据提供设计实现.尽管没有直接的实现方法,却能够使用一些变通的方式完毕类似的功能。
2.1 传统轮询
在 Web早期,这一点常使用meta刷新实现。这将自己主动指示浏览器在指定秒数之后又一次装载页面,从而支持简陋的轮询(polling)。比如在HTML文件里增加
<META HTTP-RQUIV="Refresh" CONTENT=12>,实际上就是 HTTP 头标告知浏览器每 12 秒更新一次文档。
长处 :不须要server端的配置。
缺点 :
a) 糟糕的用户体验
b) 对server的压力非常大,而且造成带宽的极大浪费。
2.2 Ajax 轮询
Ajax隔一段时间(通常使用JavaScript的setTimeout函数)就去server查询是否有改变,从而进行增量式的更新。可是间隔多长时间去查询成了问题,由于性能和即时性造成了严重的反比关系。间隔太短,连续不断的请求会冲垮server,间隔太长,务器上的新数据就须要越多的时间才干到达客户机。
长处:
a) 不须要太多server端的配置。
b) 减少带宽的负荷(由于server返回的不是完整页面)。
缺点:
a) 对server的压力并不会有明显的降低。
b) 实时性差,有一定的延迟。
应用: 这是一项很常见的技术,比如,大多数 webmail应用程序就是通过这样的技术在电子邮件到达时显示电子邮件的。
2.3 Comet
Comet方式通俗的说就是一种长连接机制(long lived http)。相同是由Browser端主动发起请求,可是Server端以一种似乎非常慢的响应方式给出回答。这样在这个期间内,服务器端能够使用同一个connection把要更新的数据主动发送给Browser。因此请求可能等待较长的时间,期间没有不论什么数据返回,可是一旦有了新的数据,它将马上被发送到客户机。Comet又有非常多种实现方式,可是总的来说对Server端的负载都会有添加.尽管对于单位操作来说,每次仅仅须要建议一次connection,可是因为connection是保持较长时间的,对于 server端的资源的占用要有所添加。
长处: 实时性好(消息延时小);性能好(能支持大量用户)
缺点: 长期占用连接,丧失了无状态高并发的特点。
应用: 股票系统、实时通讯。
2.4 Flash XML Socket
这样的方案实现的基础是:一、Flash提供了 XMLSocket类。二、 JavaScript 和 Flash的紧密结合:在 JavaScript能够直接调用 Flash程序提供的接口。
缺点:
a) 由于XMLSocket没有HTTP隧道功能,XMLSocket类不能自己主动穿过防火墙;
b) 由于是使用套接口,须要设置一个通信port,防火墙、代理server也可能对非HTTP通道port进行限制;
应用: 网络聊天室,网络互动游戏。
2.5 Java Applet 套接口
在client使用 Java Applet,通过 java.net.Socket或java.net.DatagramSocket或java.net.MulticastSocket 建立与server端的套接口连接,从而实现“server推送 ”。
缺点: 须要client安装 JAVA虚拟机。
3 Comet 介绍
Comet 有时也称反向 Ajax或server端推技术(server-side push)。其思想非常easy:将数据直接从server推到浏览器,而不必等到浏览器请求数据。听起来简单,可是假设熟悉Web 应用程序,尤其是HTTP协议,那么您就会知道,这绝不简单。实现Comet风格的 Web应用程序,同一时候保证在浏览器和server上的可伸缩性,这仅仅是在近期几年才成为可能。眼下一些主流站点都有类似的原理,比如:webQQ、开心网、校内等等,它们中消息动态都是採用类似的技术,仅仅是详细实现方式不一样。
COMET的精髓就在于用server与javascript来维持浏览器的长连接,同一时候完毕server端事件的浏览器端响应。这种事件广播机制是跨网络的,同一时候也是实时的。
採用了 Comet技术的server在客户机做出一个请求后,和客户机建立一个永久的连接,然后server会依据客户机的请求不断把数据包推向客户,这个推的过程是不间断的。由server推向客户机的数据在客户机的浏览器上会不断产生新的内容,并且不会产生Client
pull那样的HTML文档头,从而大大降低了延迟的时间,向(server响应--客户机请求)同步迈进了一步。
server推送通常效率要比client拖曳效率高,由于它不必为兴许数据建立新的连接。由于始终保持连接,即使没有传输数据时也是这样,因此server必须愿意分配这些TCP/IPport,对于TCP/IPport数有限的server这将是一个严重的问题。
client拖曳效率低,由于这必须每次为传送数据建立新的连接。可是它不必始终保持连接。在实际情况中,建立HTTP连接通常须要花费相当多的时间,多达一秒甚至很多其它。因此从性能上考虑,server推送对于终于用户更有吸引力,特别是对于须要常常更新信息的情况下。
server推送相对client拖曳的还有一点优势是,server推送相对照较easy控制。比如,server每一次推送时都保持一个连接,但它又随时能够关闭当中的不论什么连接,而不须要在server上设置特殊的算法。而client拖曳在相同的情况下要麻烦很多,它每次要与server建立连接,server为了处理将client拖曳请求与特定的终于用户匹配等情况,须要使用相当麻烦的算法。
如上所述,在server推送中,多个响应中连接始终保持,使server可在不论什么时间发送很多其它的数据。一个明显的优点是server全然可以控制更新数据的时间和频率。另外,这样的方法效率高,由于始终保持连接。缺点是保持连接状态会浪费server端的资源。server推送还比較easy中断。
4 Comet 实现(Java语言)
4.1 死循环法
最简单的自然是死循环法,假设使用观察者模式则能够进一步提高性能。
可是这样的做法的缺点在于client请求了这个 servlet后, web server会开启一个线程运行 servlet 的代码,而 servlet 由迟迟不肯结束,造成该线程也无法被释放。于是乎,一个client一个线程,当client数量添加时,server依旧会承受非常大的负担。
4.2 改写webserver
眼下的趋势是从 web server内部入手,用 nio ( JDK 1.4 提出的 java.nio 包)改写 request/response 的实现,再利用线程池增强server的资源利用率,从而解决问题,眼下支持这一非 J2EE 官方技术的server有 Glassfish 和 Jetty 。
JDK 1.4 版本号 ( 包含之后的版本号 ) 最显著的新特性就是添加了 NIO(New IO) ,可以以非堵塞的方式处理网络的请求,这就使得在 Java 中仅仅须要少量的线程就能处理大量的并发请求了。
Jetty 6设计来处理大量并发连接,它使用Java语言的不阻塞 I/O(java.nio)库而且使用优化的输出缓冲架构。Jetty也有一个处理长连接的杀手锏:一个称为 Continuations的特性。
Grizzly 作为 GlassFish 中很重要的一个项目,就是用 NIO 的技术来实现应用server中的高性能纯 Java 的 HTTP 引擎。 Grizzly 还是一个独立于 GlassFish 的框架结构,能够单独用来扩展和构建自己的server软件。
特点: 使用 NIO 不是一件简单的技术,它的一些特点使得编程的模型比原来堵塞的方式更为复杂。
4.3 使用框架
基于 Java 的成熟的server推送框架有 DWR 。
DWR是一个开放源代码的使用Apache许可协议的解决方式,它包括server端Java库、一个 DWR
servlet以及 JavaScript库。尽管 DWR不是 Java平台上唯一可用的Ajax-RPC 工具包,可是它是最成熟的,并且提供了很多实用的功能。从最简单的角度来说,DWR是一个引擎,能够把server端Java对象的方法公开给JavaScript 代码。使用DWR 能够有效地从应用程序代码中把Ajax的所有请求 -响应循环消除掉。这意味着client代码再也不须要直接处理XMLHttpRequest对象或者server的响应。不再须要编写对象的序列化代码或者使用第三方工具才干把对象变成XML。甚至不再须要编写servlet代码把 Ajax请求调整成对 Java域对象的调用。
DWR 从 2.0開始添加了 push 功能 , 也就是在异步传输的情况下能够从 Web-Server 端发送数据到 Browser
一个简单的dwr推送程序
第一步 将dwr相关的jar包导入到project
第二步 配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<!-- 设置是否同意使用dwr推送技术 -->
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>maxWaitAfterWrite</param-name>
<param-value>-1</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
</web-app>
第三步编写com.im.service.SendPushService类
public class SendPushService {
//发送消息
public void send(String msg) {
System.out.println("==========调用了send方法==========");
ScriptBuffer scriptBuffer = new ScriptBuffer(); //构造js脚本
WebContext webContext=WebContextFactory.get();
ScriptSession myScSession = webContext.getScriptSession();
scriptBuffer.appendScript("dwrtest(");
scriptBuffer.appendData(msg);
scriptBuffer.appendScript(")");
Util util = new Util(myScSession);
util.addScript(scriptBuffer); //向client推送消息
}
}
第四步 在dwr.xml文件定义向外暴露的接口
<allow>
<create creator="new" javascript="SendPushService">
<param name="class" value="com.im.service.SendPushService"/>
</create>
</allow>
第五步: 编写jsp文件.
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns=" http://www.w3.org/1999/xhtml">
<head>
<base href="${basePath }" />
<script type='text/javascript' src='${basePath}dwr/engine.js'></script>
<script type='text/javascript' src='${basePath}dwr/util.js'></script>
<script type='text/javascript' src='${basePath}dwr/interface/SendPushService.js'></script>
<script type="text/javascript">
function hello(){
SendPushService.send("第一个dwr推程序");
}
/**由dwr在后台调用这种方法**/
function dwrtest(data){
alert(data);
}
</script>
<title>第一个dwr推程序</title>
</head>
<body onload="dwr.engine.setActiveReverseAjax(true);">
<input type="button" value="点击我" onclick="hello();" />
</body>
</html>
转载请标明出处 http://blog.csdn.net/shimiso
技术交流群:173711587
Web端server推送技术原理分析及dwr框架简单的使用的更多相关文章
- Web端服务器推送技术原理分析及dwr框架简单的使用
1 背景 “服务器推送技术”(ServerPushing)是最近Web技术中最热门的一个流行术语.它是继“Ajax”之后又一个倍受追捧的Web技术.“服务器推送技术”最近的流行跟“Ajax ”有着密切 ...
- 基于HTTP协议之WEB消息实时推送技术原理及实现
很早就想写一些关于网页消息实时推送技术方面的文章,但是由于最近实在忙,没有时间去写文章.本文主要讲解基于 HTTP1.1 协议的 WEB 推送的技术原理及实现.本人曾经在工作的时候也有做过一些用到网页 ...
- SSE(Server-sent events)技术在web端消息推送和实时聊天中的使用
最近在公司闲着没事研究了几天,终于搞定了SSE从理论到实际应用,中间还是有一些坑的. 1.SSE简介 SSE(Server-sent events)翻译过来为:服务器发送事件.是基于http协议,和W ...
- 基于Web的数据推送技术(转)
基于Web的数据推送技术 对于实时性数据显示要求比较高的系统,比如竞价,股票行情,实时聊天等,我们的解决方案有以下几种.1. HTTP请求发送模式,一般可以基于ajax的请求,比如每3秒一次访问下服务 ...
- Web服务器主动推送技术
HTTP协议遵循经典的客户端-服务器模型,客户端发送一个请求,然后等待服务器端的响应,服务器端只能在接收到客户端的请求之后进行响应,不能主动的发送数据到客户端. 客户端想要在不刷新页面的情况下实时获取 ...
- 我有 7种 实现web实时消息推送的方案,7种!
技术交流,公众号:程序员小富 大家好,我是小富- 我有一个朋友- 做了一个小破站,现在要实现一个站内信web消息推送的功能,对,就是下图这个小红点,一个很常用的功能. 不过他还没想好用什么方式做,这里 ...
- Webserver推送技术
server推送(Server Push) 推送技术的基础思想是将浏览器主动查询信息改为server主动发送信息.server发送一批数据,浏览器显示这些数据,同一时候保证与server的连接.当se ...
- SpringBoot2.x服务器端主动推送技术
一.服务端推送常用技术介绍 服务端主流推送技术:websocket.SSE等 1.客户端轮询:ajax定时拉取后台数据 js setInterval定时函数 + ajax异步加载 定时向服务 ...
- [译]servlet3.0与non-blocking服务端推送技术
Non-blocking(NIO)Server Push and Servlet 3 在我的前一篇文章写道如何期待成熟的使用node.js.假定有一个框架,基于该框架,开发者只需要定义协议及相关的ha ...
随机推荐
- Hdu 5050 Divided Land
题目要求就是做求两个二进制数的gcd,如果是用java的话,这题很简单.但也可以用C++做,只能先给自己留下这个坑了,还在研究c++的做法. import java.math.BigInteger; ...
- VC++中的头文件包含问题
在一些大的工程中,可能会包含几十个基础类,免不了之间会互相引用(不满足继承关系,而是组合关系).也就是需要互相声明.好了,这时候会带来一些混乱.如果处理得不好,会搞得一团糟,根据我的经验,简单谈谈自已 ...
- iOS学习之NSAttributedString(富文本)
NSAttributedString 叫做富文本,是一种带有属性的字符串,通过它可以轻松的在一个字符串中表现出多种字体.字号.字体大小等各不相同的风格,还可以对段落进行格式化,一般都是对可变富文本(N ...
- FMDB的基本应用
FMDB简介 iOS中原生的SQLite API在进行数据存储的时候,需要使用C语言中的函数,操作比较频繁.于是,就出现了一系列将AQLite API进行封装的库,例如FMDB.PlausibleDa ...
- node.js第十课(HTTPserver)
概念:Node.js提供了http模块.当中封装了一个高效的HTTPserver和一个简单的HTTPclient. http.server是一个基于事件的HTTP服务器.内部用C++实现 ...
- linux命令sysctl使用
以前没有注意过这个命令,直到有次在单位安装greenplum的时候,在没有配置系统参数的情况下,出现了设备空间不足的报错信息. 当然,安装的不是我的本机,而是公用的服务器,编辑修改系统参数后,仍然出现 ...
- Linux下的在线播放神器
Linux下的在线播放神器:一个是Amarok缺点是,每个音乐源都要更新后才能播放. 在一个就是中国造的:linux deepin下的深度音乐,缺点就是连不上.反正我是连不上
- 翻转句子中单词的顺序 C语言
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.句子中单词以空格符隔开. 为简单起见,标点符号和普通字母一样处理. 比如将"I am a student"转化为&q ...
- 模式匹配KMP
字符串朴素模式匹配算法的2种实现: //1.朴素的模式匹配算法,用while实现 int StrStr_While(const char* pStr, const char* pSub, int* p ...
- hdu1540之线段树单点更新+区间合并
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...