我想使用 Zend_Http_Client 访问新的 Twitter Stream API。问题是,对该网页 ( http://stream.twitter.com/1/statuses/sample.json ) 的 HTTP 请求从未完成但一直在加载。
所以即使我将 Zend_Http_Client 设置为 setStream(),我也无法获取它发出的信息。
这是我目前的逻辑:
$httpClient = new Zend_Http_Client("http://stream.twitter.com/1/statuses/sample.json");
$httpClient->setAuth("username", "password");
$httpClient->setStream("/tmp/twitter_stream");
flush();
ob_flush();
$response = $httpClient->request("GET");
// Never get here... :(
Zend_Debug::dump($response);
flush();
ob_flush();
while(true)
{
echo fgets($response->getStream());
flush();
ob_flush();
}
现在,一旦我开始请求,我就永远不会进入 while 循环。 Zend Framework 所做的是,它写入一个文件。
我之所以要使用 Zend_Http_Client 是因为我以后必须使用 OAuth 访问该 Stream API,而 Zend_Oauth 依赖于 Zend_Http_Client。
如有任何帮助,我们将不胜感激。
最佳答案
据我所知,目前唯一可能的方法是扩展 Zend_Http_Client_Adapter_Socket,从旧的 Zend_Client_Http_Adapter_Socket 复制 write 方法并将您的自定义逻辑插入 do...while 循环(参见//CUSTOM LOGIC此处在方法的末尾评论):
<?php
class App_Http_Client_Adapter_Socket extends Zend_Http_Client_Adapter_Socket
{
/**
* Read response from server
*
* @return string
*/
public function read()
{
// First, read headers only
$response = '';
$gotStatus = false;
$stream = !empty($this->config['stream']);
while (($line = @fgets($this->socket)) !== false)
{
$gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
if ($gotStatus)
{
$response .= $line;
if (rtrim($line) === '')
break;
}
}
$this->_checkSocketReadTimeout();
$statusCode = Zend_Http_Response::extractCode($response);
// Handle 100 and 101 responses internally by restarting the read again
if ($statusCode == 100 || $statusCode == 101)
return $this->read();
// Check headers to see what kind of connection / transfer encoding we have
$headers = Zend_Http_Response::extractHeaders($response);
/**
* Responses to HEAD requests and 204 or 304 responses are not expected
* to have a body - stop reading here
*/
if ($statusCode == 304 || $statusCode == 204 ||
$this->method == Zend_Http_Client::HEAD)
{
// Close the connection if requested to do so by the server
if (isset($headers['connection']) && $headers['connection'] == 'close')
{
$this->close();
}
return $response;
}
// If we got a 'transfer-encoding: chunked' header
if (isset($headers['transfer-encoding']))
{
if (strtolower($headers['transfer-encoding']) == 'chunked')
{
do
{
$line = @fgets($this->socket);
$this->_checkSocketReadTimeout();
$chunk = $line;
// Figure out the next chunk size
$chunksize = trim($line);
if (!ctype_xdigit($chunksize))
{
$this->close();
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception('Invalid chunk size "' .
$chunksize . '" unable to read chunked body');
}
// Convert the hexadecimal value to plain integer
$chunksize = hexdec($chunksize);
// Read next chunk
$read_to = ftell($this->socket) + $chunksize;
do
{
$current_pos = ftell($this->socket);
if ($current_pos >= $read_to)
break;
if ($this->out_stream)
{
if (stream_copy_to_stream($this->socket, $this->out_stream, $read_to - $current_pos) == 0)
{
$this->_checkSocketReadTimeout();
break;
}
}
else
{
$line = @fread($this->socket, $read_to - $current_pos);
if ($line === false || strlen($line) === 0)
{
$this->_checkSocketReadTimeout();
break;
}
$chunk .= $line;
}
}
while (!feof($this->socket));
$chunk .= @ fgets($this->socket);
$this->_checkSocketReadTimeout();
if (!$this->out_stream)
{
$response .= $chunk;
}
}
while ($chunksize > 0);
}
else
{
$this->close();
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception('Cannot handle "' .
$headers['transfer-encoding'] . '" transfer encoding');
}
// We automatically decode chunked-messages when writing to a stream
// this means we have to disallow the Zend_Http_Response to do it again
if ($this->out_stream)
{
$response = str_ireplace("Transfer-Encoding: chunked\r\n", '', $response);
}
// Else, if we got the content-length header, read this number of bytes
}
elseif (isset($headers['content-length']))
{
// If we got more than one Content-Length header (see ZF-9404) use
// the last value sent
if (is_array($headers['content-length']))
{
$contentLength = $headers['content-length'][count($headers['content-length']) - 1];
}
else
{
$contentLength = $headers['content-length'];
}
$current_pos = ftell($this->socket);
$chunk = '';
for ($read_to = $current_pos + $contentLength; $read_to > $current_pos; $current_pos = ftell($this->socket))
{
if ($this->out_stream)
{
if (@stream_copy_to_stream($this->socket, $this->out_stream, $read_to - $current_pos) == 0)
{
$this->_checkSocketReadTimeout();
break;
}
}
else
{
$chunk = @fread($this->socket, $read_to - $current_pos);
if ($chunk === false || strlen($chunk) === 0)
{
$this->_checkSocketReadTimeout();
break;
}
$response .= $chunk;
}
// Break if the connection ended prematurely
if (feof($this->socket))
break;
}
// Fallback: just read the response until EOF
} else
{
do
{
if ($this->out_stream)
{
if (@stream_copy_to_stream($this->socket, $this->out_stream) == 0)
{
$this->_checkSocketReadTimeout();
break;
}
}
else
{
$buff = @fread($this->socket, 8192);
if ($buff === false || strlen($buff) === 0)
{
$this->_checkSocketReadTimeout();
break;
}
else
{
$response .= $buff;
}
// CUSTOM LOGIC HERE!!
echo $response;
flush();
ob_flush();
}
}
while (feof($this->socket) === false);
$this->close();
}
// Close the connection if requested to do so by the server
if (isset($headers['connection']) && $headers['connection'] == 'close')
{
$this->close();
}
return $response;
}
}
仍然非常欢迎任何其他建议,因为我觉得这更像是一种 hack 而不是有效的解决方案。
关于php - Zend_Http_Client - 从 Stream 读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3457015/
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,
Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba