且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何实现基本的“长轮询"?

更新时间:2023-09-24 12:27:22

它比我最初想象的要简单.).

这是一个非常基本的示例,它在 2-10 秒后发送一个简单的字符串.有三分之一的机会返回错误 404(在即将到来的 Javascript 示例中显示错误处理)

msgsrv.php

<?php如果(兰特(1,3)== 1){/* 假错误 */header("HTTP/1.0 404 未找到");死();}/* 在随机秒数 (2-10) 后发送一个字符串 */睡眠(兰特(2,10));echo("嗨!有一个随机数:" .rand(1,10));?>

注意:对于真实站点,在像 Apache 这样的常规 Web 服务器上运行它会很快占用所有工作线程"并使其无法响应其他请求.. 有办法解决这个问题,但它是建议在 Python 的 twisted 之类的东西中编写长轮询服务器",它不依赖于每个线程要求.cometD 是一种流行的(有多种语言版本),Tornado 是一个专门为此类任务而设计的新框架(它是为 FriendFeed 的长轮询代码而构建的)……但作为一个简单的例子,A​​pache 更胜一筹比够用!这个脚本可以很容易地用任何语言编写(我选择了 Apache/PHP,因为它们很常见,我碰巧在本地运行它们)

然后,在 Javascript 中,您请求上述文件 (msg_srv.php),并等待响应.当你得到一个时,你就对数据采取行动.然后你请求文件并再次等待,对数据采取行动(并重复)

下面是这样一个页面的例子.当页面加载时,它发送对msgsrv.php文件的初始请求.如果成功,我们将消息附加到#messages div,然后1秒后我们再次调用waitForMsg函数,触发等待.

1 秒 setTimeout() 是一个非常基本的速率限制器,没有它也能正常工作,但是如果 msgsrv.php always立即返回(例如,出现语法错误)——你淹没了浏览器,它很快就会冻结.***检查文件是否包含有效的 JSON 响应,和/或保持每分钟/秒的请求总数,并适当暂停.

如果页面出错,它会将错误附加到 #messages div,等待 15 秒,然后再试一次(与我们在每条消息后等待 1 秒的方式相同)

这种方法的好处是它非常有弹性.如果客户端的互联网连接中断,它将超时,然后尝试重新连接 - 这是轮询工作多长时间所固有的,不需要复杂的错误处理

无论如何,long_poller.htm代码,使用jQuery框架:

<头><title>BargePoller</title><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript" charset="utf-8"></脚本><style type="text/css" media="screen">正文{背景:#000;颜色:#fff;字体大小:.9em;}.msg{ 背景:#aaa;填充:.2em;边框底部:1px #000 实心}.old{ 背景颜色:#246499;}.new{ 背景色:#3B9957;}.error{ 背景色:#992E36;}</风格><script type="text/javascript" charset="utf-8">函数添加味精(类型,味精){/* 添加div的简单助手.type 是 CSS 类的名称(旧/新/错误).msg 是 div 的内容 */$("#messages").append("<div class='msg "+ type +"'>"+ msg +"</div>");}函数 waitForMsg(){/* 这请求 url "msgsrv.php"当它完成(或错误)*/$.ajax({类型:获取",url: "msgsrv.php",async: true,/* 如果设置为非异步,浏览器将页面显示为正在加载.."*/缓存:假,timeout:50000,/* 超时毫秒 */成功:函数(数据){/* 当对 barge.php 的请求完成时调用 */addmsg("new", 数据);/* 添加对 .msg div 的响应(使用new"类)*/设置超时(waitForMsg,/* 请求下一条消息 */1000/* ..1 秒后 */);},错误:函数(XMLHttpRequest,textStatus,errorThrown){addmsg("error", textStatus + " (" + errorThrown + ")");设置超时(waitForMsg,/* 后重试.. */15000);/* 毫秒 (15 秒) */}});};$(document).ready(function(){等待消息();/* 启动初始请求 */});头部><身体><div id="消息"><div class="msg old">BargePoll 消息请求者!