HTTP协议下的即时通讯第一章——Comet(长轮询)

标准

夜末的博客:

 前几天在学校演讲《KEEP CONNECTING》(HTTP协议下的服务器与客户端的即时通讯方案),在演讲中我提出了当前热门的Comet,这是一种相对于“定时更新”和"第三方SOCKET插件"来说更好的方案,我们可以称它为长轮询。

 当年我研究长轮询的时候,它可能是当时最中和的方案,既兼大部分客户端又减少服务器的投入成本,可那个时候HTML5才刚刚问世,几乎没有丝毫市场占有率,而如今HTML5飞速发展,到目前为止已经坐拥了52%的市场占有率。不可否认HTML5是未来的趋势,长轮询只不过是一个临时的过度罢了,这点我也在演讲中提到了。所以在这里长轮询只是随便带过一下,重点讲HTML5下服务器与客户端即时通讯的实现。

HTML5市场占有率

 

/*            Comet(长轮询)的实现            */

 长轮询的实现是利用AJAX和服务器端配合完成的一种模拟服务端推送的方案。简单的说就是客户端发送一个请求到服务端后,服务端保持住连接,并且检测是否有最新的数据,如果有就返回数据,等客户端接收到新数据后便会关闭当前连接并再次发送一个新的连接,然后重复以上步骤。

运行流程图:

 

客户端代码(comet.html):

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Keep connecting</title> <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.1.min.js"></script> <style type="text/css"> body{ width:650px; font: normal normal normal 20px 'lucida grande',tahoma,verdana,arial,sans-serif; line-height:1.28; direction:ltr; color:#333; } #body{ width:600px; margin:50px auto; } #content{ line-height:2; margin-top: 30px; background: #E0EEE0; font-weight:bold; padding: 10px; } #word{ padding:6px; width:500px; font-weight:bold; font-size:19px; color:#333; margin-left:10px; } </style> <script type="text/javascript"> var url = 'server.php'; var timestamp = 0; /* 连接函数 */ function connect(){ $.ajax({ data : {'timestamp' : timestamp }, url : url, type : 'get', timeout : 0, success : function(data){ timestamp = data.timestamp; $("#content").append('<div> - ' + data.msg + '</div>'); }, error : function(){ setTimeout(function(){ connect();}, 5000); }, complete : function(){ setTimeout(function(){ connect();}, 100); }, dataType : "json" }) } /* 消息发送函数 */ function send(msg){ $.ajax({ url : url, data : {'msg' : msg }, type : 'get' }) } /* 当页面加载时执行connect()函数 */ $(function($){ connect(); }) </script> </head> <body> <div id="body"> <form action="" method="get" onsubmit="send($('#word').val());$('#word').val('');return false;"> <input type="text" name="word" id="word"/> <input type="submit" name="submit" value="Send" style="height:40px; margin-left:10px;"/> </form> <div id="content"> </div> </div> </body> </html>

 

 

服务端代码(server.php):

<?php //禁止IE缓存 header("Cache-Control: no-cache, must-revalidate"); set_time_limit(0); $filename = dirname(__FILE__).'/data.txt'; // 把客户端发来的消息写到data.txt中 $msg = isset($_GET['msg']) ? $_GET['msg'] : ''; if ($msg != '') { file_put_contents($filename,$msg); die(); } // 循环判断文件是否被修改 $lastmodif = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0; $currentmodif = filemtime($filename); while ($currentmodif <= $lastmodif) { usleep(10000); // 睡眠10毫秒,防止CPU负荷 clearstatcache(); //清除文件状态缓存 $currentmodif = filemtime($filename); } // return a json array $response = array(); $response['msg'] = file_get_contents($filename); $response['timestamp'] = $currentmodif; echo json_encode($response); flush(); ?>

长轮询运行效果演示:http://seven.qmzh.net/comet/comet.html

 

HTML5市场占有率数据出处:http://streaminglearningcenter.com/articles/stat-of-the-week-html5-desktop-market-share-at-581-max.html

发表评论