抛出问题: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(data) { //console.log(data); json = JSON.parse(data); 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)); /** * 开始轮询 * @param number spend AjaxGet 的速度 单位是毫秒 */ this.open = function(spend) { var onmessage = this.onmessage; var url = this.url; if(typeof spend == ‘undefined‘) spend = 5000; if(this.PollType == ‘AjaxGet‘) { //采用轮询 this.resource = {}; this.resource.lockInt = setInterval(function(){ try{ $.get(url,{},function(json){ if(typeof onmessage == ‘function‘) onmessage(json); }); }catch(e){ alert(e.message); } },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) { if(typeof onmessage == ‘function‘) onmessage(e.data); } this.resource.onerror = function(e) { if(this.readyState == 2) alert(‘连接没有被建立,或者已经关闭,或者发生了某个致命错误‘); } } } /** * 关闭轮询 */ this.close = function() { if(this.resource) this.resource.close(); } }
服务端代码:
<?php header("Content-type: text/html; charset=utf-8"); date_default_timezone_set("Asia/Shanghai"); $result = array(‘code‘=>0,‘msg‘=>‘拉取成功‘,‘data‘=>‘当前时间是:‘.date(‘Y-m-d H:i:s‘)); $result = json_encode($result); $PollType = isset($_GET[‘PollType‘]) ? trim($_GET[‘PollType‘]) : ‘‘; 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:1000‘."\n\n"; //告诉客户端,按 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
时间: 2024-10-11 13:00:23