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 打印乘法口诀表

    package cn.lijun.demo6; public class Test3 { public static void main(String[] args) { for(int j=1;j& ...

  2. JAVA核心技术I---JAVA基础知识(对象与类)

    一:规范 将每一个类存在一个单独的源文件中 Employee.java public class Employee { private int age; private float salay; pr ...

  3. js中的blob,图片base64URL,file之间的关系

    js的base64编码和解码 英文是这样的:// atob() 将base64解码 // btoa() 将字符串转码为base64 var str = 'javascript'; window.bto ...

  4. Linux记录-shell获取hdfs used使用

    #!/bin/bash export JAVA_HOME=/app/jdk/jdk1.8.0_92 export HADOOP_HOME=/app/hadoop export HADOOP_CONF_ ...

  5. IT术语

    目录: 心跳检测 故障切换 主从配置 负载均衡 集群LVS 多集群横向扩容 纵向扩容 CDN DOS DDOS 会话跟踪 CSRF

  6. Docker 从入门到放弃(三)镜像使用

    当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载. 下面我们来学习: 1.管理和使用本地 Docker ...

  7. 解析ArcGis的字段计算器(三)——文本型字段计算,编号那些事儿

    实际操作中我们一般会将编号字段定义为文本型,因为编号不是序号,序号是一个递增数值,而编号往往是一个数字串代码. 本篇无说明的均使用VBScript语句1.怎么编号?最简单的编号—>直接在编号字段 ...

  8. Python中late-binding-closures

    2018-01-03 @望京 示例1 >>> b = [] >>> for i in range(5): ... b.append(lambda :i) ... & ...

  9. Win32程序框架

    // WinMsg.cpp : 定义应用程序的入口点. // #include "stdafx.h" #include <stdio.h> #include " ...

  10. 【由浅入深理解java集合】(二)——集合 Set

    上一篇文章介绍了Set集合的通用知识.Set集合中包含了三个比较重要的实现类:HashSet.TreeSet和EnumSet.本篇文章将重点介绍这三个类. 一.HashSet类 HashSet简介 H ...