首页 > 服务器 主动 推送 客户端浏览器 消息***

服务器 主动 推送 客户端浏览器 消息***

前言

通常情况下,无论是web浏览器还是移动app,我们与服务器之间的交互都是主动的,客户端向服务器端发出请求,然后服务器端返回数据给客户端,客户端浏览器再将信息呈现,客户端与服务端对应的模式是: 客户端请求--服务端响应,这种机制对于信息变化不是特别频繁的应用尚可,但对于实时要求高、海量并发的应用来说显得捉襟见肘,尤其在当前业界移动互联网蓬勃发展的趋势下,高并发与用户实时响应是 Web 应用经常面临的问题,比如金融证券的实时信息,Web 导航应用中的地理位置获取,社交网络的实时消息推送,新闻的订阅,天气的提醒等。这些情况下,需要服务器主动推送消息给客户端。

那么在这样的模式下,会有几个问题需要我们思考下:

1.应用服务器如何确定每一个应用所在的设备

2.服务器端是如何将消息推送到客户端的,客户端又不像服务器有一个固定的地址

带着这些疑问我们来研究一下目前有哪些技术可以解决该问题:

一、Ajax轮询

所谓的Ajax轮询,其实就是定时的通过Ajax查询服务端,客户端按规定时间定时像服务端发送ajax请求,服务器接到请求后马上返回响应信息并关闭连接。

这种技术方式实现起来非常简单,但是这种方式会有非常严重的问题,就是需要不断的向服务器发送消息询问,这种方式会对服务器造成极大的性能浪费。

还有一个类似的轮询是使用JSONP跨域请求的方式轮询,在实现起来有差别,但基本原理都是相同的,都是客户端不断的向服务器发起请求。

优点

实现简单。

缺点

这是通过模拟服务器发起的通信,不是实时通信,不顾及应用的状态改变而盲目检查更新,导致服务器资源的浪费,且会加重网络负载,拖累服务器。

二、Comet

Comet,基于 HTTP 长连接的 "服务器推" 技术,能使服务器端主动以异步的方式向客户端程序推送数据,而不需要客户端显式的发出请求,目前有两种实现方式:

1. 基于 AJAX 的长轮询(long-polling)方式

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

  1. 服务器端会阻塞请求直到有数据传递或超时才返回。
  2. 客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
  3. 当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。

基于长轮询的服务器推模型

 

 

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

长轮询 (long polling) 是在打开一条连接以后保持并等待服务器推送来数据再关闭,可以采用HTTP长轮询和XHR长轮询两种方式:

(1). HTTP 和JSONP方式的长轮询

把 script 标签附加到页面上以让脚本执行。服务器会挂起连接直到有事件发生,接着把脚本内容发送回浏览器,然后重新打开另一个 script 标签来获取下一个事件,从而实现长轮询的模型。

(2).XHR长轮询

这种方式是使用比较多的长轮询模式。

客户端打开一个到服务器端的 AJAX 请求然后等待响应;服务器端需要一些特定的功能来允许请求被挂起,只要一有事件发生,服务器端就会在挂起的请求中送回响应并关闭该请求。客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接;如此循环。

现在浏览器已经支持CROS的跨域方式请求,因此HTTP和JSONP的长轮询方式是慢慢被淘汰的一种技术,建议采用XHR长轮询。

优点

客户端很容易实现良好的错误处理系统和超时管理,实现成本与Ajax轮询的方式类似。

缺点

需要服务器端有特殊的功能来临时挂起连接。当客户端发起的连接较多时,服务器端会长期保持多个连接,具有一定的风险。

  1. >>在这里简单的说明下长轮询,长连接的概念
  2. 轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接。优点:后端程序编写比较容易。
  3. 缺点:请求中有大半是无用,浪费带宽和服务器资源。
  4. 实例:适于小型应用。
  5.  
  6. 长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
  7. 优点:在无消息的情况下不会频繁的请求。
  8. 缺点:服务器hold连接会消耗资源。
  9. 实例:WebQQHi网页版、Facebook IM
  10.  
  11. 另外,对于长连接和socket连接也有区分:
  12.  
  13. 长连接:在页面里嵌入一个隐蔵iframe,将这个隐蔵iframesrc属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。
  14. 优点:消息即时到达,不发无用请求。
  15. 缺点:服务器维护一个长连接会增加开销。
  16. 实例:Gmail聊天
  17.  
  18. Flash Socket在页面中内嵌入一个使用了Socket类的 Flash 程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通信,JavaScript在收到服务器端传送的信息后控制页面的显示。
  19. 优点:实现真正的即时通信,而不是伪即时。
  20. 缺点:客户端必须安装Flash插件;非HTTP协议,无法自动穿越防火墙。
  21. 实例:网络互动游戏。

2. 基于 Iframe 及 htmlfile 的流(streaming)方式

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

基于流方式的服务器推模型

 

 

Comet的优缺点

优点: 实时性好(消息延时小);性能好(能支持大量用户)

缺点: 长期占用连接,丧失了无状态高并发的特点。

Comet实现框架

1. Dojo CometD —— http://cometdproject.dojotoolkit.org/

2. DWR —— http://directwebremoting.org/dwr/index.html

3. ICEfaces —— http://www.icefaces.org/main/home/

4. GlassFish Grizzly —— https://grizzly.dev.java.net/

CometD 目前实现 Comet 比较成熟, DWR 弱一些。 ICEfaces 更商业化,实现得很成熟。 Grizzly 是基于GlassFish ,也很成熟。CometD, DWR 开源性好。

Comet实现要点

不要在同一客户端同时使用超过两个的 HTTP 长连接

我们使用 IE 下载文件时会有这样的体验,从同一个 Web 服务器下载文件,最多只能有两个文件同时被下载。第三个文件的下载会被阻塞,直到前面下载的文件下载完毕。这是因为 HTTP 1.1 规范中规定,客户端不应该与服务器端建立超过两个的 HTTP 连接, 新的连接会被阻塞。而 IE 在实现中严格遵守了这种规定。

HTTP 1.1 对两个长连接的限制,会对使用了长连接的 Web 应用带来如下现象:在客户端如果打开超过两个的 IE 窗口去访问同一个使用了长连接的 Web 服务器,第三个 IE 窗口的 HTTP 请求被前两个窗口的长连接阻塞。

所以在开发长连接的应用时, 必须注意在使用了多个 frame 的页面中,不要为每个 frame 的页面都建立一个 HTTP 长连接,这样会阻塞其它的 HTTP 请求,在设计上考虑让多个 frame 的更新共用一个长连接。

服务器端的性能和可扩展性

一般 Web 服务器会为每个连接创建一个线程,如果在大型的商业应用中使用 Comet,服务器端需要维护大量并发的长连接。在这种应用背景下,服务器端需要考虑负载均衡和集群技术;或是在服务器端为长连接作一些改进。

应用和技术的发展总是带来新的需求,从而推动新技术的发展。HTTP 1.1 与 1.0 规范有一个很大的不同:1.0 规范下服务器在处理完每个 Get/Post 请求后会关闭套接口连接; 而 1.1 规范下服务器会保持这个连接,在处理两个请求的间隔时间里,这个连接处于空闲状态。 Java 1.4 引入了支持异步 IO 的 java.nio 包。当连接处于空闲时,为这个连接分配的线程资源会返还到线程池,可以供新的连接使用;当原来处于空闲的连接的客户发出新的请求,会从线程池里分配一个线程资源处理这个请求。 这种技术在连接处于空闲的机率较高、并发连接数目很多的场景下对于降低服务器的资源负载非常有效。

但是 AJAX 的应用使请求的出现变得频繁,而 Comet 则会长时间占用一个连接,上述的服务器模型在新的应用背景下会变得非常低效,线程池里有限的线程数甚至可能会阻塞新的连接。Jetty 6 Web 服务器针对 AJAX、Comet 应用的特点进行了很多创新的改进。

控制信息与数据信息使用不同的 HTTP 连接

使用长连接时,存在一个很常见的场景:客户端网页需要关闭,而服务器端还处在读取数据的堵塞状态,客户端需要及时通知服务器端关闭数据连接。服务器在收到关闭请求后首先要从读取数据的阻塞状态唤醒,然后释放为这个客户端分配的资源,再关闭连接。

所以在设计上,我们需要使客户端的控制请求和数据请求使用不同的 HTTP 连接,才能使控制请求不会被阻塞。

在实现上,如果是基于 iframe 流方式的长连接,客户端页面需要使用两个 iframe,一个是控制帧,用于往服务器端发送控制请求,控制请求能很快收到响应,不会被堵塞;一个是显示帧,用于往服务器端发送长连接请求。如果是基于 AJAX 的长轮询方式,客户端可以异步地发出一个 XMLHttpRequest 请求,通知服务器端关闭数据连接。

在客户和服务器之间保持“心跳”信息

在浏览器与服务器之间维持一个长连接会为通信带来一些不确定性:因为数据传输是随机的,客户端不知道何时服务器才有数据传送。服务器端需要确保当客户端不再工作时,释放为这个客户端分配的资源,防止内存泄漏。因此需要一种机制使双方知道大家都在正常运行。在实现上:

  1. 服务器端在阻塞读时会设置一个时限,超时后阻塞读调用会返回,同时发给客户端没有新数据到达的心跳信息。此时如果客户端已经关闭,服务器往通道写数据会出现异常,服务器端就会及时释放为这个客户端分配的资源。
  2. 如果客户端使用的是基于 AJAX 的长轮询方式;服务器端返回数据、关闭连接后,经过某个时限没有收到客户端的再次请求,会认为客户端不能正常工作,会释放为这个客户端分配、维护的资源。
  3. 当服务器处理信息出现异常情况,需要发送错误信息通知客户端,同时释放资源、关闭连接。

三,websocket方式

 WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket通讯协议于2011年被IETF定为标准RFC 6455,WebSocketAPI被W3C定为标准。在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

 

 

 由于websocket技术要说明白的话所需要的篇幅不小,所以会在之后的单独文章中介绍下websocket的使用方式,这里就不做详细的说明了。

总结

根据以上技术的优缺点和具体业务需要,可以选择合适的技术进行应用。

转载于:https://www.cnblogs.com/jiangzhaowei/p/9881104.html

更多相关:

  • 滑块式验证码用户通过拖动滑块行为来完成校验,支持PC端及移动端。可以将用户拖动行为的时间、精度,滑动轨迹等信息到服务器,然后进行后台算法验证。特别介绍Blazor 版本的滑块验证码 传送门在线演示效果图快速开始组件依赖 font-awesomeCSS将引入样式表的 标签复制并粘贴到 中,并放在所有其他样式表之前。JS将引入脚本的 用...

  • Ktor 是一个使用 Kotlin 以最小的成本快速创建 Web 应用程序的框架。Ktor 是一个用于在连接系统(connected systems)中构建异步服务器和客户端的 Kotlin 框架。它由 Kotlin 团队创建,因此,它充分利用了 Kotlin 的语言特性,为开发者提供出色的体验和运行时性能。import io.kto...

  • l VDI (Virtual Desktop Infrastructure)VDI构架采用的“集中存储、集中运算”构架,所有的桌面以虚拟机的方式运行在服务器硬件的虚拟化层上,桌面以图像传输的方式发送到客户端。l IDV (Intelligent Desktop Virtualization) 由于VDI方案对服务器资源、网络带宽要求比...

  • 受昨晚闰秒问题影响,今天内网和线上的ATS服务器都出现了CPU负载增高的问题,参见下面的截图 下面是tsar监控到负载异常记录,从今天(20150701)早上8:05分开始: 我们内网和线上的服务器Linux kernel内核版本都是 经过实践摸索,发现如下规律: 1.如果已经开启ntpd,如果昨晚没有关闭n...

  • 下面的安装假定是以root用户身份进行的,Linux服务器已经安装好系统,磁盘已经做好分区。 首先需要认识我们的Linux服务器的硬件配置和软件情况 硬件配置: DELL R720 2U服务器 CPU  8核 Intel(R) Xeon(R) CPU E5-2609 0 @ 2.40GHz 内存 32G 硬盘  系统盘 /...

  • 文章目录搭建实验平台使用Unity的准备工作在PC端安装连接Hololens软件Hololens设置开始连接吧绘制显示PC端网页监控...

  •  将多次卷积和池化后的图像展开进行全连接,如下图所示。  全连接层需要把输入拉成一个列项向量          比如你的输入的feature map是2X2,那么就需要把这个feature map 拉成4X1的列向量,如果你的feature map 的channels是3,也就是你的输入是3X2X2,也就是相当于有了12个像素点,...

  •   注意,前情提示: 本代码基于《Node.js(nodejs)对本地JSON文件进行增、删、改、查操作(轻车熟路)》 传送门Node.js(nodejs)对本地JSON文件进行增、删、改、查操作(轻车熟路)_你挚爱的强哥❤给你发来1条消息❤-CSDN博客 首先安装 cnpm i nodejs-websocket 在/a...

  • Ubuntu 配置自带桌面共享 1、在setting>>shareing>>remote 选择on 如果用ubunutu直接远程连接的话已经可以了, 2、在ubuntu下使用系统自带的remmina连接 vnc类型 直接输入ip地址 3、如果在windows下面连接的话需要把加密选项关闭 内容: 安装dconf-edito...

  • 第四节 RabbitMQ在C#端的应用-客户端连接 原文:第四节 RabbitMQ在C#端的应用-客户端连接 版权声明:未经本人同意,不得转载该文章,谢谢 https://blog.csdn.net/phocus1/article/details/87357911 1.在VS2013中新建控制台程序,然后添加引用:.NE...

  • 文章目录前言函数描述代码实例如何得到客户端的IP 和 端口号 前言 当使用tcp服务器使用socket创建通信文件描述符,bind绑定了文件描述符,服务器ip和端口号,listen将服务器端的主动描述符转为被动描述符进行监听之后,接口accept通过三次握手与客户端建立连接 TCP 编程模型如下: 函数描述 #i...