一、背景介绍

传统web请求,是显式的向服务器发送http Request,拿到Response后显示在浏览器页面上。这种被动的交互方式不能满足对信息实时性要求高的应用,譬如聊天室、股票交易行情、在线游戏等。Ajax轮询虽然可以解决这个问题,但是会带来增加服务器负担、带宽浪费,并且这种实现方式不够优雅。而Comet技术就是为此而生的。

本文只探讨基于浏览器的web端服务器推技术。服务器推技术在现实应用中有一些解决方案,主要分两类:一类是需要浏览器额外安装插件,基于套接口传送信息或者是基于RMI、CORBA进行远程调用,另一类则无需浏览器安装任何插件,就是本文着重讲的HTTP长连接技术:Coment。Alex Russell(Dojo Toolkit 的项目 Lead)称这种基于 HTTP 长连接、无须在浏览器端安装插件的“服务器推”技术为“Comet”。

写本文的目的:网上的资料比较零碎,博客园的文章基本都是代码+代码,或者直接翻译别人的成果,而对于原理性的东西讲的很少。本文就是给有兴趣或者即将开发服务器推技术的程序员一个技术概览,摸清行内来龙去脉。我比较忌讳对一种新技术,上来就Focus到某个具体的技术上而不能自拔,盲人摸象。我们在定系统框架,敲定技术解决方案之前应该比较各个实现方案技术的优缺点,这样才能做出好的系统来。

二、Comet实现模型

1.HTTP Long Polling:基于 AJAX 的长轮询方式
    众所周知,AJAX可以异步调用XMLHttpRequest对象发送HttpRequest,Javascript响应处理函数根据服务端返回的信息对HTML页面显示进行更新。而使用AJAX实现服务器推与传统AJAX应用的不同之处在于:

a.服务器端会阻塞请求直到有数据返回或者超时;

b.客户端JS响应函数在处理完服务端返回的信息后会再次发出请求,重新建立连接;

如图1所示,因为这种方案基于 AJAX,具有以下一些优点:请求异步发出;无须安装插件;IE、Mozilla FireFox 都支持 AJAX。

图1:基于 AJAX 的长轮询方式

2.HTTP Streaming:基于 Iframe 及 htmlfile 的流方式
    通过在 HTML 页面里嵌入一个隐蔵帧,然后将这个隐蔵帧的 SRC 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。如图2所示。

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

两种方案对比:

a.在对返回的数据处理方面:方案2(IFrame)返回的是对客户端javascript调用,,如“<script type="text/javascript">js_func(“data from server ”)</script>”。服务器端将返回的数据作为客户端 JavaScript 函数的参数传递;客户端浏览器的 Javascript 引擎在收到服务器返回的 JavaScript 调用时就会去执行代码。而方案1(AJAX)返回的是数据,通过JS可以很方便的操作DOM。

b.使用IFrame还有一个明显不足:IE、Morzilla Firefox 下端的进度栏都会显示加载没有完成,而且 IE 上方的图标会不停的转动,表示加载正在进行。不过这个问题已经被Google技术人员解决,并应用到Gtalk中,解决方案是:ActiveX 控件解决 iframe 请求长连接时 IE 的加载显示问题,原文地址:“What else is burried down in the depth’s of Google’s amazing JavaScript?”。

三、实际开发时应该注意的问题

对于一个实际的应用而言,系统的稳定性和性能是非常重要的。将 HTTP 长连接用于实际应用,很多细节需要考虑。

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

这个是由于HTTP 1.1 规范中规定:客户端不应该与服务器端建立超过两个的 HTTP 连接,新的连接会被阻塞。所以,在设计上考虑让多个 frame(AJAX)共用一个长连接。

2.服务器端的性能和可扩展性一般的WEB服务器是为每个连接创建一个线程,所以在使用Comet时,服务器要维护大量并发,长期存在的长连接。在这种背景下,就需要服务器负载均衡和集群技术,或者在服务端做一些优化。这篇文章:http://rdc.taobao.com/blog/cs/?p=1062的测试表明:200万个Http长连接占用率19G服务器内存,一个大约9kb;所以,你可以算一下你的服务器最多可以维护多少个长连接。

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

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

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

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

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

客户端不知道何时服务器才有数据传送。服务器端需要确保当客户端不在状态(工作)时,释放为这个客户端分配的资源,防止内存泄漏。因此需要一种机制使双方知道大家都在正常运行。

四、Comet框架介绍由于Comet早在2006.2月就提出来了,所以并不是什么新鲜玩意,框架还是很多的,譬如:Dojox.cometd,Pushlet,SingalR。

Dojox.cometd:Comet概念的的提出者Alex Russel主导的Dojo项目分支,Dojo 基金会提出了 Bayeux 协议用来标准化 Comet 应用中客户端和服务器端之间的通信。Dojox.cometd 实现了 Bayeux 协议的客户端部分,使用 HTTP 长轮询来作为数据的传输通道。

Pushlet:基于HTTP流,而不是AJAX长轮询。一个开源的 Comet 框架,Pushlet 使用了观察者模型:客户端发送请求,订阅感兴趣的事件;服务器端为每个客户端分配一个会话 ID 作为标记,事件源会把新产生的事件以多播的方式发送到订阅者的事件队列里。貌似只支持Java。

SingalR:基于AJAX长轮询。ASP.NET团队开发的一个开源的.net framework库和Jquery插件。集成的客户端与服务器库,基于浏览器的客户端和基于 ASP.NET 的服务器组件可以借助它来进行双向多步对话。

五、SingalR的MVC4实践

1.安装与运行环境:(Nuget) install-package Microsoft.AspNet.SignalR ,注意:PM>后面不要有空格。

或者到GitHub上下载源码:https://github.com/SignalR/SignalR

这里顺便提一下,SingalR服务端需要支持的OS:

  • Windows Server 2012
  • Windows Server 2008 r2.
  • Windows 8
  • Windows 7
  • Windows Azure

.net framework4,4.5。WebSocket必须是4.5.

IIS7,7.5 ,integrated Mode,而不是classic Mode, WebSockets必须IIS8。更加详尽的说明,请自行参考:http://www.asp.net/signalr/overview/getting-started/supported-platforms

2.核心实现:

首先,我们需要引用SignalR,用Nuget不需要自己手工添加,应为你的asp.net mvc项目自动添加好一切。

服务端Library:

Microsoft.AspNet.SignalR.Core
Microsoft.AspNet.SignalR.Owin
Microsoft.AspNet.SignalR.SystemWeb
Owin
Newtonsoft.Json

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;namespace DeepleoComet
{public class ChatHub : Hub{public void Send(string name, string message){// Call the addNewMessageToPage method to update clients.Clients.All.addNewMessageToPage(name, message);}}
}

客户端的Jquery插件:

jquery.signalR-1.1.3.min.js.

@{ViewBag.Title = "Chat";
}<h2>Chat</h2><div class="container"><input type="text" id="message" /><input type="button" id="sendmessage" value="Send" /><input type="hidden" id="displayname" /><ul id="discussion"></ul>
</div>@section scripts {<script src="~/Scripts/jquery.signalR-1.1.3.js"></script><script src="~/signalr/hubs"></script><script>$(function () {var chat = $.connection.chatHub;chat.client.addNewMessageToPage = function (name, message) {$('#discussion').append('<li><strong>' + htmlEncode(name)+ '</strong>: ' + htmlEncode(message) + '</li>');};$('#displayname').val(prompt('Enter your name:', ''));$('#message').focus();$.connection.hub.start().done(function () {$('#sendmessage').click(function () {chat.server.send($('#displayname').val(), $('#message').val());$('#message').val('').focus();});});});function htmlEncode(value) {var encodedValue = $('<div />').text(value).html();return encodedValue;}</script>
}

实现效果:

开两个页面:http://localhost:11968/ ,分别键入name,就可以实现一个简单的聊天室功能了。

六、题外话:Comet的替代品:Html5的WebSocket

在浏览器中通过http仅能实现单向的通信,comet可以一定程度上模拟双向通信,但效率较低,并需要服务器有较好的支持; flash中的socket和xmlsocket可以实现真正的双向通信,通过 flex ajax bridge,可以在javascript中使用这两项功能. 可以预见,如果websocket一旦在浏览器中得到实现,将会替代上面两项技术,得到广泛的使用.面对这种状况,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并达到实时通讯。

真是相见恨晚啊,才知道还有这么个东西,居然Web端也有了全双工的Socket,貌似有个socket.io还支持IE6,我和我的小伙伴们都惊呆了。

比较好的关于WebSocket文章:http://www.cnblogs.com/wei2yi/archive/2011/03/23/1992830.html

参考资料

1.原理:http://www.ibm.com/developerworks/cn/web/wa-lo-comet/

2.DOJO原理与实践:http://www.ibm.com/developerworks/cn/web/wa-lo-w2fpak-comet/

3.淘宝200W长链接测试与优化:http://rdc.taobao.com/blog/cs/?p=1062

4.长连接百科:http://baike.baidu.com/view/2831907.htm

5.博客园Comet专题:http://kb.cnblogs.com/page/112185/

6. Jetty+Dojo+Tomcat:http://blog.csdn.net/garfier/article/details/5942826

7.SingalR官网:http://signalr.net/

8.Singal辅导:http://www.asp.net/signalr

转载于:https://www.cnblogs.com/deepleo/p/Comet.html

Comet:基于 HTTP 长连接的“服务器推”技术解析相关推荐

  1. Comet:基于 HTTP 长连接的“服务器推”技术 (实例)

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

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

    作者:周 婷 (zhouting@cn.ibm.com), 软件工程师, IBM 中国软件开发技术实验室 来源:http://www.ibm.com/developerworks/cn/web/wa- ...

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

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

  4. comet - “服务器推”技术

    概念 comet :基于 HTTP 长连接的"服务器推"技术,是一种新的 Web 应用架构.基于这种架构开发的应用中,服务器端会主动以异步的方式向 客户端程序推送数据,而不需要客户 ...

  5. java comet_用java实现comet,基于 HTTP长连接的实现,用于从服务端实时发送信息到客户端...

    http://homelink.javaeye.com/blog/293328#comments 参考文档 http://www.ibm.com/developerworks/cn/web/wa-lo ...

  6. 如何实现android和服务器长连接呢?推送消息的原理

    前言:现在的大多数移动端应用都有实时得到消息的能力,简单来说,有发送消息的主动权和接受消息的被动权.例如:微信,QQ,天气预报等等,相信好处和用户体验相信大家都知道吧. 提出问题:这种功能必须涉及cl ...

  7. 基于php和服务器推技术的web即时聊天系统,基于php和服务器推技术的Web即时聊天系统...

    基于php和服务器推技术的Web即时聊天系统① 王振兴, 黄静 [摘要]摘要: 基于http协议应用于Web端, 实现一个浏览器无关的.便于移植的.高性能的Web即时聊天系统. 系统使用服务器推技术中 ...

  8. 基于HTTPS长连接的ESP32+VS1053网络电台收音机Arduino代码

    基于HTTPS长连接的ESP32+VS1053网络电台收音机Arduino代码 代码下载地址:ESP32+VS1053网络电台收音机Arduino完整源代码.-硬件开发文档类资源-CSDN下载 硬件搭 ...

  9. pushlet实现服务器推技术

     服务器推技术: (1)由于目前我司电话系统处理来电弹屏存在一个问题,就是客户端登录系统会触发前端js不断去请求数据库数据,并反馈给前端,如果使用者一多,将会导致系统资源高消耗: (2)目前比较成 ...

最新文章

  1. matlab根据 2 6,#2.6 应用MATLAB进行模型处理
  2. UVA-10954 Add All
  3. 使用Cloud application Studio在C4C UI里创建下拉列表(dropdown list)
  4. Windows下无法新建文件夹
  5. SAP CRM呼叫中心里的Java stack
  6. kotlin 和java 混编
  7. LQ训练营(C++)学习笔记_枚举算法
  8. Linux按压缩率大小排序,Linux下常用压缩 解压命令与压缩比率对比
  9. php点击按钮查询,管理界面点击按钮打开查询功能
  10. Spring mvc 参数类型转换
  11. 对象存储 OSS > 开发指南 > 存储类型 > 存储类型介绍
  12. Yapi 部署及遇到的坑
  13. 数据结构和算法———P6 线性表
  14. mongodb用户信息管理案例
  15. 计算机图形学与OpenGL
  16. 小白Mybatis学习笔记,mybatis入门
  17. 微信登录显示连接失败,请检查网络
  18. 王绍伟:你不是非得和别人一样---转载
  19. google、bing ,baidu 等搜索引擎 查询参数
  20. Echarts—地图的基本实现

热门文章

  1. python 批量更换图片格式脚本
  2. 2014多校第一场A题 || HDU 4861 Couple doubi
  3. 关于win10更新后谷歌浏览器打开卡慢或者无法上网的问题解决
  4. 搭载鸿蒙处理器的手机,荣耀Magic3被曝光,或采用安卓与鸿蒙双系统,搭载麒麟9000处理器...
  5. python猜数字代码_Python版的文曲星猜数字游戏代码
  6. 平板电脑安装软件_分享一个将平板作为电脑分屏的软件(文末有链接)
  7. AIoT让一个屏有了100种用法
  8. 端云互联 3.0 击破云原生开发的痛点
  9. Galgame研发日志:预算爆炸,问题不大
  10. 《刺客信条:英灵殿》全面分析:浅谈公式化开放世界