Comet 是一种高级的Ajax技术,实现了服务器向页面实时推送数据的技术,应用场景有体育比赛比分和股票报价等。

实现Comet有两种方式:长轮询与http流

长轮询是短轮询的翻版,短轮询的方式是:页面定时向服务器发送请求,看有没有更新的数据。

而长轮询的方式是,页面向服务器发起一个请求,服务器一直保持tcp连接打开,知道有数据可发送。发送完数据后,页面关闭该连接,随即又发起一个新的服务器请求,在这一过程中循环。

短轮询和长轮询的区别是:短轮询中服务器对请求立即响应,而长轮询中服务器等待新的数据到来才响应,因此实现了服务器向页面推送实时,并减少了页面的请求次数。

http流不同于上述两种轮询,因为它在页面整个生命周期内只使用一个HTTP连接,具体使用方法即页面向浏览器发送一个请求,而服务器保持tcp连接打开,然后不断向浏览器发送数据。

以下为客户端实现长轮询的方法:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
result = xhr.responseText
console.log(result);
xhr.open('get', 'test2.php'); //在获得数据后重新向服务器发起请求
xhr.send(null);
}
}
xhr.open('get', 'test2.php');
xhr.send(null);

以下为客户端实现http流的方法:

var xhr = new XMLHttpRequest();
received = 0; //最新消息在响应消息的位置
xhr.onreadystatechange = function(){
if(xhr.readyState == 3){
result = xhr.responseText.substring(received);
console.log(result);
received += result.length;
}else if(xhr.readyState == 4){
console.log("完成消息推送");
}
}
xhr.open('get', 'test1.php');
xhr.send(null);

以下为服务器端实时推送的实现方法,以php为例:

<?php
ini_set('max_execution_time', 10);
error_reporting(0);
$i = 0;
while(true){ //不断推送消息
echo "Number is $i\n";
ob_flush(); //将php缓存冲出
flush(); //从php缓存中输出到tcp缓存
$i++;
sleep(1);
}
?>

页面接受到数据效果如下:

另外大多数浏览器实现了SSE(Server-Sent Events,服务器发送事件) API,SSE支持短轮询、长轮询和HTTP流,使用方式如下:

客户端:

var source = new EventSource("test.php");    //生成EventSource对象,url必须同源
var len = 0;
source.onopen = function(){ //如果连接断开,还会自动重新连接
console.log("connection opend");
}
source.onmessage = function(event){ //event.data返回最新的消息
var data = event.data.substring(0);
len = data.length;
console.log(data);
}

服务器端:

<?php
ini_set('max_execution_time', 10);
header('Content-type: text/event-stream'); //服务器响应的MIME类型必须是text/event-stream
$i = 0;
while(true){
echo "data: Number is $i\n"; //固定格式: 数据必须以data:为前缀
echo "\n\n"; //数据以空行,即'\n\n'分隔,每一个空行触发一次message事件
ob_flush();
flush();
$i++;
sleep(1);
}
?>

参考资料: 《javascript 高级程序设计》

实现Comet(服务器推送)的两种方式:长轮询和http流的更多相关文章

  1. 实现web消息推送的技术和采用长轮询corundumstudio介绍

    实时消息的推送,PC端的推送技术可以使用socket建立一个长连接来实现.传统的web服务都是客户端发出请求,服务端给出响应.但是现在直观的要求是允许特定时间内在没有客户端发起请求的情况下服务端主动推 ...

  2. 极光推送经验之谈-Java后台服务器实现极光推送的两种实现方式

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/6439313.html Java后台实现极光推送有两种方式,一种是使用极光推送官方提供的推送请 ...

  3. 基于comet服务器推送技术(web实时聊天)

    http://www.cnblogs.com/zengqinglei/archive/2013/03/31/2991189.html Comet 也称反向 Ajax 或服务器端推技术.其思想很简单:将 ...

  4. Comet服务器推送与SignalR

        HTTP协议是一个典型的Request/Response协议,是基于TCP/IP之上的一个应用层协议,该协议最典型的特点就是无状态且需要客户端发起Request服务端才能进行Response, ...

  5. 云服务器 ECS Linux 服务器修改时区的两种方式

    在云服务器 ECS Linux 系统中,以 Centos6.5 为例,可以通过如下两种方式,修改系统时区: 可以使用命令 tzselect,修改时区.操作示例: [root@localhost ~]# ...

  6. Comet 反Ajax: jQuery与PHP实现Ajax长轮询

    原文地址(http://justcode.ikeepstudying.com/2016/08/comet-%E5%8F%8Dajax-%E5%9F%BA%E4%BA%8Ejquery%E4%B8%8E ...

  7. ASP.NET MVC之读取服务器文件资源的两种方式

    初次认识asp.net mvc时,以为所有文件都需要走一遍路由,然后才能在客户端显示, 所以我首先介绍这一种方式 比如说:我们在服务器上有图片: ~/resource/image/5.jpg 我们就需 ...

  8. Web服务器负载均衡的几种方案 : DNS轮询

    本篇主要讲一下最简单的方案——DNS轮询. DNS轮询 大多域名注册商都支持多条A记录 的解析,其实这就是DNS轮询 ,DNS 服务器 将解析请求按照A记录 的顺序,逐一分配到不同的IP上,这样就完成 ...

  9. Nginx负载均衡的4种方式 :轮询-Round Robin 、Ip地址-ip_hash、最少连接-least_conn、加权-weight=n

    这里对负载均衡概念和nginx负载均衡实现方式做一个总结: 先说一下负载均衡的概念: Load Balance负载均衡是用于解决一台机器(一个进程)无法解决所有请求而产生的一种算法. 我们知道单台服务 ...

随机推荐

  1. java 常用的类

    一.日期操作:Calendar类和SimpleDateFormat类 public void Test1() { Calendar calendar=Calendar.getInstance(); S ...

  2. 字符类型char、字符串与字符数组、字符数组与数据数组区别

    字符类型是以ASCII码值运算的:小写字母比相应的大写字母大32,其中A=65,a=97 Esc键 27(十进制).'\x1B'(十六进制).'\33'(八进制) 转义字符:\0 空字符     AS ...

  3. 数据库事务的隔离以及spring的事务传播机制

    数据库的事务隔离: MySQL InnoDB事务的隔离级别有四级,默认是“可重复读”RR(REPEATABLE READ). oracle默认的是提交读.RC 未提交读(READ UNCOMMITTE ...

  4. C++: 可变参数;

    可变参数,即参数的个数是动态变化的, 可多可少. 1. 可变参数: 可变参数一般采用”..."表示,用在宏上表示变参宏, 如: #define WriteLine(format,...) p ...

  5. 信用评分卡 (part 5 of 7)

    python信用评分卡(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_camp ...

  6. springboot中通用mapper结合mybatis generator的使用

    通用mapper就是指的是  tk.mybatis  包下的.这个是通用mapper就是说自动生成的dao层需要继承这个框架提供的mapper类.而我们之前用的org.mybatis这个最开始是普通的 ...

  7. 2.抽象工厂(Abstract Factory)

    常规的对象创建方法: //创建一个Road对象 Road road =new Road(); new 的问题: 实现依赖,不能应对“具体实例化类型”的变化.解决思路:    封装变化点-----哪里变 ...

  8. vue this.$router.push和this.$route.path的区别

    this.$router 实际上就是全局路由对象任何页面都可以调用 push(), go()等方法: this.$route  表示当前正在用于跳转的路由器对象,可以调用其name.path.quer ...

  9. SQL记录-ORACLE 12C初体验

    1.部署 2.使用

  10. Django基于正则表达式匹配URL

    在Django1.X中,是这样匹配的. 在Django2.X中,是这样匹配的. Django2.X中开始需要用re_path模块进行正则表达式匹配了,太JB坑了,卡了好久这个问题,最后还是问群里面的高 ...