之前的一个项目,情况如下:
页面使用Ajax定时刷新一次,每次刷新就到后台中查询比对,如果数据有变化,则刷新,更新数据,但是没变化得话也会刷新一次,所以这很纠结。。。
现在想做成从后台推送的效果:
如果后台数据有变化,就把数据推送到前台,页面数据更新,否则,不变化!
B/S架构中服务器向浏览器推送数据在很多场合都有需求,比如实时的监控报警、实时的调度,等等。凡是对实时性要求越高的场景,越是需要服务器及时、准确地向浏览器推送数据。这里我们就讨论一下在B/S架构下,可以实现从服务器向浏览器推送数据的几种技术及其相应的特点。
基于HTTP协议
1. HTTP协议的特点
纯的HTTP协议在本质上是无状态、无连接的,它基于请求/响应的工作模式,使得浏览器在每次发生请求的时候和服务器建立连接,当接收到响应的时候断开连接;在这种情况下,要让服务器主动向浏览器发送数据是不可能的。
技术总是为需求服务的,在很多浏览器需要及时获取服务器数据更新的需要下,技术人员们变通地发明了一些基于HTTP协议的“伪”长连接技术,实现了服务器数据向浏览器的“准”推送。
2. 定时刷新
定时刷新是最粗糙的实现快速感知服务器数据变化的方法,原理就是不停地刷新页面从而显示最新的服务器端数据。定时刷新从技术上大体有两种实现方法:一是通过HTML的META标签设置页面刷新间隔,比如以下的标签会在浏览器中每隔5秒刷新当前页面:
5秒之后刷新本页面:
5秒之后转到梦之都首页:
这种方式会看到页面有明显的刷新,用户体验会比较差;与此相对应的另外一种方式就是AJAX,在JavaScript脚本中添加一个定时器,每隔一定时间向服务器发送一个AJAX请求,得到响应以后去更新页面的内容。以下JavaScript代码会每隔10秒发送一个AJAX请求去更新当前页面的部分内容:
setInterval(function(){sendAJAXRequest()},10000);
如图 1是定时刷新的模型图:
定时刷新这种模式相当于一个下级每隔一段时间打电话给上级,请示当前指示。当然,如果在这个时间段内发生了一些情况,他们之间是没办法沟通的,所以信息并不是“实时”的;另外,刷新间隔到底设置多少合适也是个问题,服务器的负担也比较大。
3. 轮询
轮询也是通过AJAX进行的,它与AJAX定时刷新的区别仅在于接收到AJAX响应以后的工作。定时刷新完全是浏览器主动的,在浏览器和服务器之间存在一定的断开间隔;而轮询这种方式会在AJAX响应中再次发送AJAX请求,也就是说当响应结束,浏览器和服务器之间一旦断开连接的时候,浏览器会再次发送请求建立连接。
轮询这种模式相当于一个下级不停给上级打电话请示,上级指示下达以后挂了电话,下级可能去执行指示或者不执行,但是随即下级将再次给上级打电话继续请示。这种模式可以保证数据更新比较实时,但是服务器负担也是一个问题。
顺便提一下,轮询这种模式一般会在浏览器的XMLHttpRequest的readyState为4(响应数据传输结束)的时候调用回调函数,此时连接已经关闭;但是在Firefox中支持Streaming AJAX模式,也就是XMLHttpRequest的readyState为3(响应数据仍在传输)的时候调用回调函数,此时连接尚未关闭。
2. Java消息服务(JMS)
JMS是一组公开的Java API,它定义了与消息相关的接口和语义,目前JMS已经成为J2EE中的重要组成部分。
当有客户端连接到JMS服务器的时候,JMS的连接工厂会根据连接类型来创建一个虚拟连接,这个连接会具体负责消息的传递;在这个连接建立完成后,会产生一个会话,会话中保存了消息生产者或消息消费者的信息;消息的消费者会对感兴趣的消息目的地(队列或主题)建立一个监听,消息的生产者则负责把消息发送到这个目的地上。
另外JMS还有一些值得一提的特点,比如支持事务性会话、可以设置消息的持久性、设置消息的优先级、允许消息过期、可以构建长期订阅等。这些特性在各种企业级应用环境下都有可能提高应用的功能或性能。
实现JMS的商业中间件有IBM MQSeries、BEA WebLogic JMS等;开源中间件有OpenJMS、Apache ActiveMQ等。
3.websocket