更新:请查看本消息末尾的新代码,使用 cURL 很容易实现,但我第一次的方法有误。
我无法使用CURLOPT_READFUNCTION使 Twitter 流 API 与cURL配合工作,但是使用 fsockopen() 和 fread()
成功了。我不知道为什么 readfunction 没有起作用,因为我以前在其他地方成功过。但这可能与响应数据是“流式传输”而不是使用 HTTP 分块编码发送有关。基本上,我的读取函数从未被调用,因此无法处理数据。
我现在使用的方法:
- 使用 fsockopen 连接到
ssl://stream.twitter.com
- 使用
fputs
发出用于流数据的基本 HTTP 请求
- 消费 HTTP 响应标头,并确保没有错误
- 使用
fread
在一个无限循环中读取一定量的数据
- 每当读取到一片数据时,就会调用一个内部缓冲区函数
- 缓冲函数将新数据附加到缓冲区中
- 然后缓冲函数尝试处理缓冲区中的所有消息(如果我们有一个或多个完整的消息)
- 处理每个消息时,缓冲区将被减少,直到为空,然后函数返回并重新读取数据
我已经让它运行了几个小时,没有发生过断开连接的情况,且已经处理了 30,000 条消息而没有出现错误。
基本上,我实现了一个回调系统,以便每当从缓冲区中读取到完整的消息时,它都会调用用户定义的回调函数并传递json消息,这样应用程序就可以对消息执行其需要的任何操作(例如插入数据库)。
我没有简短的代码段可以在此处发布,但如果您愿意,请通过访问我的个人资料中列出的网站并填写联系表格与我联系,我很乐意分享。也许我们可以一起合作,如果有人感兴趣。我只是为了好玩而这么做,我对 Twitter 没有兴趣,并且不出于金融原因使用它。我可能最终会将它放在 GitHub 上。
编辑:
下面是一些 cURL 代码,它将连接到流 API 并在可用时将 JSON 消息传递给回调函数。此示例使用 gzip 编码以节省带宽。
<?php
$USERNAME = 'youruser';
$PASSWORD = 'yourpass';
$QUERY = 'nike';
function writeCallback($handle, $data)
{
$json = json_decode($data);
if (isset($json->user) && isset($json->text)) {
echo "@{$json->user->screen_name}: {$json->text}\n\n";
}
return strlen($data);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://stream.twitter.com/1/statuses/filter.json?track=' . urlencode($QUERY));
curl_setopt($ch, CURLOPT_USERPWD, "$USERNAME:$PASSWORD");
curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'writeCallback');
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
curl_setopt($ch, CURLOPT_USERAGENT, 'tstreamer/1.0');
curl_exec($ch);
$info = curl_getinfo($ch);
var_dump($info);