Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Comet——服务器推送解决方案

Comet——服务器推送解决方案

原创
作者头像
千墨
修改于 2018-07-05 03:22:04
修改于 2018-07-05 03:22:04
1.5K0
举报
文章被收录于专栏:rhjrhj

浏览器需要资源时,发起请求向服务器“要”,这个很容易,地球人都知道。

服务器有资源更新,想向浏览器“推”,这个好像就有点麻烦了。

Comet就是这么个词,描述技术、协议和为浏览器提供可行且可扩展的低延迟数据传输的解决方案,,,的集合。

使用场景

  • 监控:天气啊、水库啊、核反应堆啊、外星人入侵啊......咳咳,等等。
  • 报价:0700涨到300块啦!南北车又跳水啦!恒生指数三万两千点啦!
  • 消息:腾讯在线教育web化课堂聊天系统 = =、

还是蛮希望0700涨到300块的对吧(虽然这跟我并没有什么关系= =)。类似这些消息,需要服务器即时地更新到浏览器,因为浏览器并不知道恒生指数有没有涨到三万两千点。这个问题的实现方案就是今天要记录的Comet。

方案一:轮询

代码语言:txt
AI代码解释
复制
function ajax(data){
	var xhr = new XMLHttpRequest();
    xhr.open('get', '/cgi-bin/xxx', true);
    xhr.onreadystatechange = function(){
    	if (xhr.readyState == 4) {
        	if (xhr.status == 200) {
            	......
            }
        }
    }
    xhr.send(data);
}
setTimeout(function(){ajax({"data":"hehe"});}, 2000);

估计看到这两个字的时候各位已经准备好臭鸡蛋要丢上来了。是的,这个词汇生来就不招人待见,因为它就是这么一个蛋疼的过程。

浏览器君:恒指上三万了吗?

服务器桑:没有

浏览器君:恒指上三万了吗?

服务器桑:没有

浏览器君:恒指上三万了吗?

服务器桑:没有

浏览器君:恒指上三万了吗?

服务器桑:没有

浏览器君:恒指上三万了吗?

服务器桑:没有

呵呵呵呵。。。。。。。。不多说了反正也不会用。

方案二:长轮询

穿个马甲我就不认识你啦?!其实别说,穿个马甲好像确实有点不一样了。

代码语言:txt
AI代码解释
复制
function longPoll(data, cbk){
	var xhr = new XMLHttpRequest();
    var url = '/cgi-bin/xxx';
    xhr.onreadystatechange = function(){
    	if (xhr.readyState == 4) {
        	if (xhr.status == 200) {
            	cbk(xhr.responseText);
                xhr.open('get', url, true);
                xhr.send(otherData);
            }
        }
    }
	xhr.open('get', url, true);
	xhr.send(data);
}

浏览器君:恒指上三万了吗?

浏览器君嗑瓜子中......

浏览器君吃薯片中......

浏览器君跳秧歌中......

服务器桑:没有

浏览器君:恒指上三万了吗?

浏览器君走钢丝中......

浏览器君碎大石中......

浏览器君住院中......

服务器桑:上了

浏览器君执行“赶紧卖”回调函数。

恩,区别就在于服务器在没有响应的时候会把请求hold住,直到有消息要返回或者超时返回

从浏览器的角度来看,长轮询的办法保持了有效的请求,又避免了大量无效请求,并且即时性更好,这是一种可行的方案。

方案三:永久帧

永久帧(forever-frame)的方法是打开一个隐藏的iframe,用这个iframe去请求一个HTTP1.1的trunked编码文档,这是为增量读取超大型文档而生的,即把iframe当作一个不断增加内容的文档,然后在增量文档中生成script标签调用预定义的回调函数,这里也有jsonp的思想在里面。

代码语言:txt
AI代码解释
复制
function foreverFrame(url, callback) {
	var ifm = document.createElement('iframe');
    ifm.style.display = 'none';
    ifm.src = url + '?callback=parent.foreverFrame.callback';
    this.callback = callback;
}

与jsonp类似对吧,事先定义回调函数,请求参数带上回调函数名,只不过这里涉及父子iframe之间的通信,要注意跨域问题。

关于iframe跨域问题,隔壁团队有个不错的实现方案。 见http://www.alloyteam.com/2013/11/the-second-version-universal-solution-iframe-cross-domain-communication/

然后服务器就发送一堆消息到iframe中

代码语言:txt
AI代码解释
复制
<script>
parent.foreverFrame.callback('hello world!');
</script>
<script>
parent.foreverFrame.callback('hello Mars!');
</script>

这个方法的问题在于,没有办法实现可靠的错误处理或者跟踪连接的状态,因为所有的连接和数据都是由浏览器通过script标签来处理的,于是某一端什么时候断开了咱们并不知道。

方案四:xhr流

xhr流(XMLHttpRequest Streaming)也是通过标准的XMLHttpRequest对象获得的,但是需要在readyState为3的时候去访问数据,这样就不必等待连接关闭之后再操作数据。

代码语言:txt
AI代码解释
复制
function xhrStreaming(url, callback) {
	var xhr = new XMLHttpRequest();
    xhr.open('post', url, true);
    //保存上次返回的文档位置
    var lastSize;
    xhr.onreadystatechange = function() {
    	var newResponseText = "";
        if (xhr.readyState > 2) { 
        	newResponseText = xhr.responseText.slice(lastSize);
        	lastSize = xhr.responseText.length;
        	callback(newResponseText);
        }
        if (xhr.readyState == 4) {
        	xhrStreaming(url, callback);
        }
    }
    xhr.send(null);
}

其实跟永久帧的方法也类似,只不过是把iframe获取内容的方式改成了ajax,然后在xhr内部处理增量逻辑、回调和重发。

这里需要注意的是链接时间需要有超时限制,否则内存性能会受到影响,另外单个请求返回数据需要限定长度,不能无限增大。

终极方案:WebSocket

这个名字大家都不陌生了,HTML5协议中的BS全双工通信解决方案,真正的高富帅,实力与智慧的结合,地位和财富的象征。

代码语言:txt
AI代码解释
复制
//名字叫“猥琐”的函数
function ws(url, callback) {
	var ws = new WebSocket(url);
    
    ws.onopen = function() {
    	ws.send(xxx);
    }
    ws.onmessage = function(e) {
    	callback(e.data);
    }
    ws.onclose = function(e) {
    	...
    }
}

美如画。。。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Comet——服务器推送解决方案
Comet就是这么个词,描述技术、协议和为浏览器提供可行且可扩展的低延迟数据传输的解决方案,,,的集合。
IMWeb前端团队
2019/12/04
1.3K0
Comet——服务器推送解决方案
34.Ajax
优先级 如果发送的是【普通数据】 jQuery XMLHttpRequest iframe 如果发送的是【文件】 iframe jQuery(FormData) XMLHttpRequest(FormData) 原生Ajax Ajax主要就是使用 【XmlHttpRequest】对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件) 1、XmlHttpRequest对象介绍 XmlHttpRequest对象的主要方法: a. void op
zhang_derek
2018/04/11
2K0
原生AJAX请求教程
ajax 即 Asynchronous Javascript And XML,AJAX 不是一门的新的语言,而是对现有持术的综合利用。本质是在 HTTP 协议的基础上以异步的方式与服务器进行通信.
老马
2018/07/31
2.8K0
同源策略和跨域解决方案
下表给出了相对http://a.xyz.com/dir/page.html同源检测的示例: 
py3study
2020/01/19
1.6K0
同源策略和跨域解决方案
前端架构师之01_JavaScript_Ajax
响应头用于告知客户端本次响应的基本信息,包括服务器程序名、内容的编码格式、缓存控制等。
张哥编程
2024/12/13
4890
Web基础知识
响应头用于告知客户端本次响应的基本信息,包括服务器程序名、内容的编码格式、缓存控制等。
张哥编程
2024/12/13
6020
Web前端-Ajax基础技术(上)
ajax是浏览器提供一套的api,用于向服务器发出请求,接受服务端返回的响应,通过javascript调用,实现通过代码控制请求与响应,实现网络编程。
达达前端
2019/07/03
1.6K0
Web前端-Ajax基础技术(上)
原生——ajax
什么是Ajax?(前后端数据交互) Asynchronous JavaScript and XML(异步JavaScript和XML)
FinGet
2019/06/28
2.1K0
Ajax与Comet
Ajax(Asynchronous JavaScript + XML的简写)可以向服务器请求数据而无需卸载(刷新)页面,带来更好的用户体验。 Ajax技术的核心是XMLHttpRequest对象(简称XHR)。
奋飛
2019/08/15
7800
AJAX全套
对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上。
用户1214487
2022/03/26
1.8K0
ajax全套
对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上。
菲宇
2019/06/13
3.3K0
ajax全套
深入探究跨域请求及其解决方案
随着互联网的发展,越来越多的网站和应用程序涌现出来,但是在这些网站和应用程序之间进行数据交互时,会遇到一些问题,其中最常见的问题就是跨域请求。本文将深入探究跨域请求的定义、原因以及解决方案。
Front_Yue
2023/12/29
1.2K0
深入探究跨域请求及其解决方案
【通信】前端中的几类数据交互方式
服务器 res.setHeader(‘Access-Control-Allow-Origin’,‘*’);
前端修罗场
2023/10/07
3940
【通信】前端中的几类数据交互方式
「深入浅出」前端开发中常用的几种跨域解决方案
看完本文可以系统地掌握,不同种跨域解决方案间的巧妙,以及它们的用法、原理、局限性和适用的场景
用户6835371
2021/06/01
1K0
「深入浅出」前端开发中常用的几种跨域解决方案
【JavaWeb】学习笔记——Ajax、Axios
AJAX(Asynchronous JavaScript And XML):异步的JavaScript 和 XML
鸡先生
2022/10/29
9420
【JavaWeb】学习笔记——Ajax、Axios
什么是跨域?解决方案有哪些?
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
用户1093975
2018/08/03
15.3K0
什么是跨域?解决方案有哪些?
WEB 前端跨域解决方案
2.) 资源嵌入: <link> 、 <script> 、 <img/> 、 <frame> 等 dom 标签,还有样式中 background:url() 、 @font-face() 等文件外链
chuchur
2022/10/25
1K0
js异步处理方案
回调函数是最早的解决异步编程方法 原生ajax和setTimoue都是利用回调函数,在未来某一时刻执行指定方法
刘嘿哈
2022/10/25
3.1K0
史上最全的AJAX
对于web应用程序:用户浏览器发送请求.服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML),渲染并显示浏览器上·
Wyc
2018/09/11
4.5K0
前端常见跨域解决方案
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指”协议+域名+端口”三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
全栈程序员站长
2022/08/04
3.2K0
相关推荐
Comet——服务器推送解决方案
更多 >
LV.0
腾讯科技(成都)有限公司web前端开发
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档