Discuz教程网

关于用PHP发多个HTTP请求的经验

[复制链接]
authicon dly 发表于 2011-11-16 22:20:55 | 显示全部楼层 |阅读模式
这两天在改删除SQUID缓存的程序,因为页面缓存是HASH到不同的SQUID服务器上的,所以每次删除都要先FSOCKOPEN一次,这样效率很低,所以计划改成按SQUID IP分组发送,一次连接,多次请求,最后断开,但这种方式,之前并没有人使用过,只能摸着石头过河。
原理很简单,准备发送时,先FSOCKOPEN,取得连接句柄后,循环进行多次发送,并将返回的结果保存,断开连接。研究了大半天,遇到几个问题,最后好在都解决了。记录如下。
首先,是否可以这样操作?答案是,可以,但在发送请求是要将CONNECTION一项设为KEEP-ALIVE,这样,在每次发送完请求后,与目标服务器的连接会被保留。在一般的SOCKET操作说明中,程序往往会写成这样,CONNECTION:CLOSE这样实际上是在请求发送成功后断开连接,但一般人对HTTP协议不是太熟悉,能用就行,所以可能不会注意这里。就像我。
第二,如果得到目标服务器的返回结果。仍用有些程序教程说事,常用的方式是:
while(!feof($fp))
{
    $line .= fgets($fp);
}
这样写没有问题,但它还是有一个隐含的问题的:当多次请求时,不能在每次请求后马上就用这个得到结果,试过的人都知道,只有第一次请求的结果能够通过这种方式得到,后面的就不行了。大概看了下,PHP的母语言C,在判断一个数据流是否EOF时,会在内部检测是否结尾时用一个变量标注,下次EOF时只检没这个标注就完了,而在第二次用EOF这样的函数检测时(其他函数的原理相同),是不可能得到结果的。解决办法是在每次发送请求后,就别进行取结果操作,而等全部请求发送完之后,再一次取回所有的结果。
问题三:EOF太慢,这个实际是个不应该出现的问题,但它确实出现了,而且我还为此困惑了好久,虽然找到了其他的解决办法,但还是觉得这问题很2。
前面说到,为子保持连接,进行重复请求,我们用了KEEP-ALIVE,但在最后取结果时,也正是因为这个KEEP-ALIVE,EOF(或是其他方法判断是否已读到数据流尾)却用了近5秒,而这5秒应该就是服务器端KEEP-ALIVE的超时时间。这里我用了个不得亦的替代方法:设置超时STREAM_SET_TIMEOUT,即在程序读取返回的结果时,如果判断EOF超时,就强行结束。这样,至少不用让程序等5秒。但其实完全不用这样做。在最后一次发送请求时,将CONNECTION设为CLOSE就可以了。就这么简单。
总得说来,用SOCKET进行一次连接多次请求的操作还是可行的。



上一篇:HTTP协议中的持久连接connection:keep-alive
下一篇:必备的15个在线网站检测工具
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2025-5-2 09:19

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表