也谈---基于 HTTP 长连接的“服务(转载)

时间:2022-09-09 17:52:48

这里指讨论基于HTTP的推技术, 诸如flash,applet之类的东西不作分析, 他们就不能说是"纯粹"的浏览器应用了.

首先是一点背景知识, 大家都知道长连接避免了tcp连接的反复建立,能够节省大量资源. 但HTTP天生就是短连接的pull式服务, 这不能说是个缺点, 只是对某些实时性服务而言有点不合适.

目前大部分浏览器和web服务器都支持keep-alive参数, 这一点可以部分解决频繁建立连接的问题.

RFC 2068 明确了浏览器与一服务器的连接数不得超于2个, IE这样办了, Firefox似乎不怎么听话.  这使得浏览器在加载包含大量图片等多媒体内容时必须等待, 也就是理论上讲, 浏览器加载一个页面时,只能同时下载2个文件, 多数包含大量多媒体信息的网页都把这些大量的多媒体文件分布的放在不同域上(可以是同一主机),以使浏览器多线程下载.

这里就会影响我们的目的, 如果是长连接, 这势必会永久的占了一个连接,  只剩一个, 好好考虑吧.

当然浏览器可以修改连接会话数配置, 方法如下. 不过如果是互联网程序, 总不能让人人都改吧.
IE缺省2个,  Firefox缺省8个.

Firefox---about:config
network.http.max-connections-per-server.

Internet Explorer---regedit
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings.
add DWORD value under it.
MaxConnectionsPerServer
MaxConnectionsPer1_0Server

方案一.  ajax轮询.
任何支持xmlhttprequest对象的浏览器都可使用, 对web服务器不作要求, 原理很简单,  ajax定时请求,  得到返回结果后更新页面.  非常简单易行,服务端代码不变.  但其根本不是推, 只是用户看上去像推, 自然对性能没有改进, 实时性也保证不了. 缺点的本身也是优点,没有占浏览器的连接资源, 也没有占web服务器的连接和进(线)程资源, 后文说明.

方案二. ajax长轮询.
似乎比方案一好一点,  xmlhttprequest请求服务, web服务器再没有更新数据时不返回,等待有新数据时才返回数据给浏览器, 服务端代码需要使用wait(),notify()方法等待和唤醒http处理进(线)程.  浏览器在得到数据或超时返回. 这样避免了多次请求,建立连接却得到没有数据更新的结果而资源浪费.  IE中由于缺乏对Streaming AJAX的支持,  在数据返回后必须重新建立连接, 而firefox则可以在 XMLHttpRequest.readystate 为 3 时(数据仍在传输中)读取数据,从而无须关闭连接,就能读取处理服务器端返回的信息。  其实这个也不是推, 只是一个长拉, 但已经比方案一进步了不少.  但它占了浏览器的连接资源, 同时也占了web服务器的连接和进(线)程资源.

方案三.基于 Iframe 及 htmlfile 的流(streaming)方式
iframe 是很早就存在的一种 HTML 标记, 通过在 HTML 页面里嵌入一个隐蔵帧,然后将这个隐蔵帧的 SRC 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。  这个似乎更好, 不需要xmlhttprequest对象, 而且这个连接理论上是永久的连接, 不会中断. 原理倒也不复杂(一些防火墙常被设置为丢弃过长的连接, 服务器端可以设置一个超时时间, 超时后通知客户端重新建立连接,并关闭原来的连接).
Iframe.src引用的web应用返回一个script脚本, 此脚本更新父页面内容.
这里有个基本概念.chunk 就是分块, 大家都用过下载工具下载过大文件,  这些工具的基本原理就是把大文件分成块,多线程下载, http协议里有块这个概念, 使得浏览器可以边下载边显示.  于是服务端代码可以有一个循环返回script块, 也很简单就是需要flush罢了.  此javascript执行, 更新父页.  方案二中Firefox Streaming AJAX与这个是一致的, 不过是这个被绝大多数浏览器支持.  与方案二一样, 此占浏览器和web服务器连接资源.

但使用这种方案,IE、Morzilla Firefox 下端的进度栏都会显示加载没有完成,而且 IE 上方的图标会不停的转动,表示加载正在进行。一个称为“htmlfile”的 ActiveX 解决了在 IE 中的加载显示问题。Alex Russell 在 “What else is burried down in the depth's of Google's amazing JavaScript?”文章中介绍了这种方法。Zeitoun 网站提供的 comet-iframe.tar.gz,封装了一个基于 iframe 和 htmlfile 的 JavaScript comet 对象,支持 IE、Mozilla Firefox 浏览器,可以作为参考.  示例为PHP代码, 当然换成别的也行.

方案二与三都需要注意一些问题.

1,因为其占用浏览器连接, 而应用最广泛的IE缺省只能用两个连接, 故不要在同一客户端同时使用超过两个的 HTTP 长连接.

2,服务器端的性能和可扩展性, 这个很重要,作为大用户的web应用, 如果使用长连接, 对服务器性能是个很大的挑战, 保持大量的连接数一般没有什么问题,一般而言, 单服务器可以支持数千个连接, 但是在传统WEB服务器实现采用了阻塞式I/O, 这种模式对每个连接使用一个进(线)程,服务器很难支撑大量的进(线)程.  所幸很多服务器都有了支持comet的方案,  其实原理很简单,就是非阻塞IO,Java中就是常说的NIO, windows,Unix-like当然更有支持.  Jetty, tomcat6,glassfish等服务器都有支持.

3控制信息与数据信息使用不同的 HTTP 连接
使用长连接时,存在一个很常见的场景:客户端网页需要关闭,而服务器端还处在读取数据的堵塞状态,客户端需要及时通知服务器端关闭数据连接。服务器在收到关闭请求后首先要从读取数据的阻塞状态唤醒,然后释放为这个客户端分配的资源,再关闭连接。
所以在设计上,我们需要使客户端的控制请求和数据请求使用不同的 HTTP 连接,才能使控制请求不会被阻塞。
在实现上,如果是基于 iframe 流方式的长连接,客户端页面需要使用两个 iframe,一个是控制帧,用于往服务器端发送控制请求,控制请求能很快收到响应,不会被堵塞;一个是显示帧,用于往服务器端发送长连接请求。如果是基于 AJAX 的长轮询方式,客户端可以异步地发出一个 XMLHttpRequest 请求,通知服务器端关闭数据连接。

4在客户和服务器之间保持“心跳”信息
在浏览器与服务器之间维持一个长连接会为通信带来一些不确定性:因为数据传输是随机的,客户端不知道何时服务器才有数据传送。服务器端需要确保当客户端不再工作时,释放为这个客户端分配的资源,防止内存泄漏。因此需要一种机制使双方知道大家都在正常运行。在实现上1).服务器端在阻塞读时会设置一个时限,超时后阻塞读调用会返回,同时发给客户端没有新数据到达的心跳信息。此时如果客户端已经关闭,服务器往通道写数据会出现异常,服务器端就会及时释放为这个客户端分配的资源。
2).如果客户端使用的是基于 AJAX 的长轮询方式;服务器端返回数据、关闭连接后,经过某个时限没有收到客户端的再次请求,会认为客户端不能正常工作,会释放为这个客户端分配、维护的资源。
3).当服务器处理信息出现异常情况,需要发送错误信息通知客户端,同时释放资源、关闭连接。

最后一句,  其实所有所有这些, 都不是推的方案,   HTTP的规范确定了请求/回复, 这些不过是看上去像推而矣,  当然后两者确实有推的意思,  如果不算最早一次请求的话^-^.

也谈---基于 HTTP 长连接的“服务(转载)的更多相关文章

  1. Comet:基于 HTTP 长连接的“服务器推”技术解析

    原文链接:http://www.cnblogs.com/deepleo/p/Comet.html 一.背景介绍 传统web请求,是显式的向服务器发送http Request,拿到Response后显示 ...

  2. Comet:基于 HTTP 长连接的“服务器推”技术

    “服务器推”技术的应用 请访问 Ajax 技术资源中心,这是有关 Ajax 编程模型信息的一站式中心,包括很多文档.教程.论坛.blog.wiki 和新闻.任何 Ajax 的新信息都能在这里找到. c ...

  3. comet基于HTTP长连接技术(java即时通信,推送技术详解)

    服务器推送技术的基础思想是将浏览器主动查询信息改为服务器主动发送信息,服务器发送一批数据,浏览器显示消息,同时保证与服务器的连接,当服务器需要再一次的发送数据,浏览器显示数据并保持连接. comet基 ...

  4. 转载:Comet:基于 HTTP 长连接的“服务器推”技术

    转自:http://www.ibm.com/developerworks/cn/web/wa-lo-comet/ 很多应用譬如监控.即时通信.即时报价系统都需要将后台发生的变化实时传送到客户端而无须客 ...

  5. [转载] Comet:基于 HTTP 长连接的“服务器推”技术

    转载自http://www.ibm.com/developerworks/cn/web/wa-lo-comet/ “服务器推”技术的应用 传统模式的 Web 系统以客户端发出请求.服务器端响应的方式工 ...

  6. 长连接锁服务优化实践 C10K问题 nodejs的内部构造 limits.conf文件修改 sysctl.conf文件修改

    小结: 1. 当文件句柄数目超过 10 之后,epoll 性能将优于 select 和 poll:当文件句柄数目达到 10K 的时候,epoll 已经超过 select 和 poll 两个数量级. 2 ...

  7. Comet:基于 HTTP 长连接的“服务器推”技术(转载)

    “服务器推”技术的应用 传统模式的 Web 系统以客户端发出请求.服务器端响应的方式工作.这种方式并不能满足很多现实应用的需求,譬如: 监控系统:后台硬件热插拔.LED.温度.电压发生变化: 即时通信 ...

  8. 【转】Comet:基于 HTTP 长连接的“服务器推”技术

    原文链接:http://www.ibm.com/developerworks/cn/web/wa-lo-comet/ 很多应用譬如监控.即时通信.即时报价系统都需要将后台发生的变化实时传送到客户端而无 ...

  9. Comet技术详解:基于HTTP长连接的Web端实时通信技术

    前言 一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Ser ...

随机推荐

  1. MDK5 STM32编译问题汇总

    MDK5 STM32编译问题汇总 WIN8.KEIL-MDK-5 编译时,出现弹窗"The ARM C/C++ Compiler 已停止工作",关闭弹窗后,编译输出的窗口中出现如下 ...

  2. 在js中获取get参数(仿PHP)

    复制粘贴即可..然后就可以在js中像PHP用$_GET['name']这样子获取get参数了!! /*--------------------(返回 $_GET 对象, 仿PHP模式)-------- ...

  3. iOS的REST服务-备

    REST式的服务最重要的三个特征就是**无状态性**(statelessness).**统一资源定位**(uniform resource identification)和**可缓存性**(cache ...

  4. 阵列中条带(stripe)、stripe unit

    摘抄:http://blog.sina.com.cn/s/blog_4a362d610100aed2.html 在磁盘阵列中,数据是以条带(stripe)的方式贯穿在磁盘阵列所有硬盘中的.这种数据的分 ...

  5. HTML5 总结-地理定位-6

    HTML5 地理定位 定位用户的位置 HTML5 Geolocation API 用于获得用户的地理位置. 鉴于该特性可能侵犯用户的隐私,除非用户同意,否则用户位置信息是不可用的. 浏览器支持 Int ...

  6. windows phone (25) Canvas元素B

    原文:windows phone (25) Canvas元素B  ZIndex 这也是一个附加属性,表示canvas的children集合内的子元素的显示顺序,在canvas中的元素默认情况下是后面的 ...

  7. 分析Sizzle引擎

    jQuery 2.0.3 源码分析Sizzle引擎 - 打造高效查询 为什么Sizzle很高效? 首先,从处理流程上理解,它总是先使用最高效的原生方法来做处理 HTML文档一共有这么四个API: ge ...

  8. C++ 处理 utf-8

    类似"abc汉字"这样的字符串是以utf-8编码; C++ 的 cout执行的操作是把参数发送给stdout,因此如果终端支持utf-8, 汉字可以使用cout打印: 比较好的办法 ...

  9. JavaScript读取对象属性遇到的问题

    JavaScript中对于对象的属性存取方式有两种:“.”操作和[]操作. “.”操作属性名通常直接写,[]操作中属性的名字通常要加引号, 而当需要读取的对象属性名是一个变量的时候,一般使用[]操作, ...

  10. webstorm设置VCS:版本控制顶部按钮

    说明: 每次都在这坑一下,浪费时间,百度只指出在哪,并没有说怎么调出来 我用的版本是10,点击下面的选项按操作设置就可以了 红色箭头:从服务器获取最新代码: 绿色箭头:提交: 白色箭头:撤销