抛出问题:web浏览器如何与服务保持通信?

方法一:Ajax轮询

方法二:EventSource轮询

方法三:websocket保持长连接

下面的解决方案是,Ajax轮询与EventSource轮询的合体。

客户端代码:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script src="jquery.min.js"></script>
<script src="PollSource.js"></script>
</head>
<body>
<h1>Server Data:</h1>
<div id="serverData"></div>
<a href="javascript:Poll.open(1000);">open poll</a>
<a href="javascript:Poll.close();">close poll</a>
<script type="text/javascript">
var serverData,Poll;
var SERVER_URL = "index.php";
window.onload = function(){
serverData = document.getElementById("serverData");
Poll = new PollSource(SERVER_URL);
Poll.onmessage = function(json) {
//console.log(json);
serverData.innerHTML = json.data;
}
}
</script>
</body>
</html>

PollSource.js代码:

/**
* PollSource javascript轮询服务器
* @param string url 服务器地址 例:www.example.com/index.php
* @param json jsonParam 传递给服务器的参数
* @author Echo
*/
function PollSource(url,jsonParam) {
this.url = url;
this.onmessage = null;
this.resource = null;
this.PollType = typeof(EventSource)=='undefined' ? 'AjaxGet' : 'EventSource';
//将轮询类型传递给服务器,以便服务器作出响应
if(typeof jsonParam == 'object') {
jsonParam['PollType'] = this.PollType;
}else{
jsonParam = {PollType:this.PollType};
}
this.url += '?';
for(var i in jsonParam) {
this.url += i+'='+jsonParam[i]+'&';
}
this.url = this.url.substring(0,(this.url.length-1));
/**
* 开始轮询
*/
this.open = function() {
var onmessage = this.onmessage;
var url = this.url;
var msg = '连接没有被建立,或者已经关闭,或者发生了某个致命错误'; //错误时不友好提示 :)
if(this.PollType == 'AjaxGet') {
//采用轮询
this.resource = {};
url += '&Seconds=';
var hangUp = false; //是否挂起
var retry = spend = 3000; //最快轮询速度 3 秒一次
this.resource.lockInt = setInterval(function(){
retry -= spend;
//alert(retry);
if(retry > 0 || hangUp) return;
hangUp = true; //挂起
$.get(url+(new Date()).getSeconds(),{},function(data){
try{
var json = JSON.parse(data);
retry = json.retry;
hangUp = false; //取消挂起
if(typeof onmessage == 'function') onmessage(json);
}catch(e){console.log(e);alert(msg);}
});
},spend);
this.resource.close = function() {
if(typeof this.lockInt == 'number') {
clearInterval(this.lockInt);
}
}
}else{
//采用服务器发送事件技术
this.resource = new EventSource(this.url);
this.resource.onmessage = function(e) {
try{
var json = JSON.parse(e.data);
if(typeof onmessage == 'function') onmessage(json);
}catch(e){
console.log(e);alert(msg);
}
}
this.resource.onerror = function(e) {
if(this.readyState == 2) alert(msg);
}
}
}
/**
* 关闭轮询
*/
this.close = function() {
if(this.resource) this.resource.close();
}
}

服务端代码:

<?php
header("Content-type: text/html; charset=utf-8");
date_default_timezone_set("Asia/Shanghai");
$retry = 9000; //AjaxGet 轮询 最快是 3000 所以这里设置的值最好是 3 的倍数 如果不是三的倍数 那么时间误差在1~2秒内
$result = array('code'=>0,'msg'=>'拉取成功','retry'=>$retry,'data'=>'当前时间是:'.date('Y-m-d H:i:s'));
$result = json_encode($result);
$PollType = isset($_GET['PollType']) ? trim($_GET['PollType']) : '';
sleep(3); //延迟 3秒 返回数据 重试时间 9秒 刚好是 客户端12秒一次刷新数据
if($PollType == 'AjaxGet') {
//header('Content-Type:application/json; charset=utf-8');
echo $result;
}else if($PollType == 'EventSource') {
header('Content-Type: text/event-stream');
echo 'data:'.$result."\n\n";
echo 'retry:'.$retry."\n\n"; //EventSource轮询速度 虽然可以设定为 1 秒 一次 但不建议
flush();
}else{
die('error');
}

测试效果:

代码下载:百度网盘

参考资源:

https://developer.mozilla.org/zh-CN/docs/Server-sent_events/EventSource
https://developer.mozilla.org/zh-CN/docs/Server-sent_events/Using_server-sent_events#Event_stream_format

javascript轮询请求服务器的更多相关文章

  1. Ajax轮询请求

    Ajax轮询请求 什么是轮询? 轮询(polling):客户端按规定时间定时向服务端发送ajax请求,服务器接到请求后马上返回响应信息并关闭连接. Ajax轮询需要服务器有很快的处理速度与快速响应. ...

  2. 常规轮询请求,客户端用Ajax调webservice的方法

    服务端发布webservice,下图方框中的一定要有 客户端代码 <script type="text/javascript"> $(document).ready(f ...

  3. 实现Comet(服务器推送)的两种方式:长轮询和http流

    Comet 是一种高级的Ajax技术,实现了服务器向页面实时推送数据的技术,应用场景有体育比赛比分和股票报价等. 实现Comet有两种方式:长轮询与http流 长轮询是短轮询的翻版,短轮询的方式是:页 ...

  4. 利用ajax短轮询+php与服务器交互制作简易即时聊天网站

    主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Server-sent Events). 本文主要介绍ajax短轮询的简易实现方式. 看懂此文 ...

  5. ajax短轮询+php与服务器交互制作简易即时聊天网站

    主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Server-sent Events). 本文主要介绍ajax短轮询的简易实现方式. 看懂此文 ...

  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. polling轮询和comet

    comet:(原意:彗星) Comet is a web application model in which a long-held(held:保留) HTTP request allows a w ...

  8. .Net MVC 实现长轮询

    什么是长轮询? 长轮询是“服务器推”技术实现方式的一种,可以将服务端发生的变化实时传送到客户端而无须客户端频繁的地刷新.发送请求. 长轮询原理? 客户端向服务器发送Ajax请求,服务器接收到请求后,保 ...

  9. 10分钟学会web通讯的四种方式,短轮询、长轮询(comet)、长连接(SSE)、WebSocket

    一般看到标题我们一般会产生下面几个问题??? 什么是短轮询? 什么是长轮询? 长连接又是什么? wensocket怎么实现呢? 他们都能实现web通讯,区别在哪呢,哪个好用呢? 接下来我们就一个个来了 ...

随机推荐

  1. 网页调用文件另存为js

    查看引用是否正常,页面添加html代码. <a id="downLoad" onclick="oDownLoad('downLoad')">下载&l ...

  2. RabbitMQ知识梳理

    RabbitMQ 基本概念 交换机类型: RabbitMQ 运转流程: AMQP协议 入门使用 安装环境: 交换机和队列: 进阶使用 消息去从 消息确认投递 消息防止丢失 过期时间 (TTL) 消息分 ...

  3. sublime中Vue高亮插件安装

    1.准备语法高亮插件vue-syntax-highlight. 下载地址: https://github.com/vuejs/vue-syntax-highlight 下载页面并下载: 解开压缩包vu ...

  4. js函数(续)

    一.全局变量和局部变量全局变量:当前js页面中均可使用的变量[声明在函数外面的变量],整个js页面中均可以使用.局部变量:声明在函数内部的变量,只能在函数内部使用.eg: var a = 1; con ...

  5. Java字符串操作工具类

    import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.lang. ...

  6. 【书评:Oracle查询优化改写】第五至十三章

    [书评:Oracle查询优化改写]第五至十三章 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知 ...

  7. day 01 预科

    目录 作业 二,Markdown基本语法 一级标题 二级标题 三级标题 作业 二,Markdown基本语法 标题 一级标题 二级标题 三级标题 四级标题 加粗 哦,更粗了 斜体 咦,我歪了 高亮 == ...

  8. Linux DNS 分离解析

    设置DNS分离解析可以对不同的客户端提供不同的域名解析记录.来自不同地址的客户机请求同一域名时,为其提供不同的解析结果. 安装 bind 包 [root@localhost ~]# yum insta ...

  9. Linux命令——parted

    参考:8 Linux ‘Parted’ Commands to Create, Resize and Rescue Disk Partitions 简介 parted是磁盘分区操作工具,支持多种磁盘分 ...

  10. docker 常见问题处理汇总

    问题一: docker执行docker info出现如下警告WARNING: bridge-nf-call-iptables is disabledWARNING: bridge-nf-call-ip ...