实现PubSubHubbub订阅
2010 12 9 11:17 PM 3339次查看
分类:Google App Engine 标签:Google App Engine, Python, RSS
在那篇文章中,我只研究了PubSubHubbub的publish(发布),而没探索subscribe(订阅),而这篇文章则是说明如何在GAE上实现PubSubHubbub订阅的。
相关的文章其实已经有了,例如Nick的《Consuming RSS feeds with PubSubHubbub》。不过订阅显得比发布要复杂些,所以我还是去读了下《PubSubHubbub 0.3协议》。
简单来说,要实现订阅一共需要2步:
- 订阅者向hub发送订阅请求,指定所需订阅的feed,并提供一个callback地址。
- Hub尝试访问callback地址,确认订阅请求。
第一步很简单,构造一个POST请求即可。其中用到的POST参数共有这些:
- hub.callback:必须参数。订阅者的callback地址。
- hub.mode:必须参数。请求类型,可为"subscribe"或"unsubscribe"。
- hub.topic:必须参数。所订阅的feed地址。
- hub.verify:必须参数。验证方式,可为"sync"或"async"。前者表示hub服务器接到这个订阅请求后,必须立刻访问callback以确认;后者表示可以之后再访问callback。由于立刻确认可以得知是否订阅成功,因此一般是用"sync";但是Google App Engine上比较蛋疼,有时候只给你一个分配instance,而导致无法响应这个请求,所以安全起见还是用"async"。
- hub.lease_seconds:可选参数。订阅的有效时间,未提供时为永久有效(或直到下次自动刷新都有效)。据我测试,pubsubhubbub.appspot.com的默认有效时间是5天。
- hub.secret:可选参数。用于hash加密的密钥,只能在HTTPS请求中发送。因为我用不到这么复杂的玩意,所以无视。
- hub.verify_token:可选参数。验证token,hub服务器访问callback时会提供这个token,你可以验证它来判断是否是自己发出的,避免别人假借你的名义来订阅或退订。
def send_subscription_request(hub, callback, mode, verify_token, feed):
memcache.set('hub_verify_token', verify_token)
data = urlencode({
'hub.callback': callback,
'hub.mode': mode,
'hub.topic': feed,
'hub.verify': 'async',
'hub.verify_token': verify_token
})
try:
response = urlfetch.fetch(hub, data, urlfetch.POST, deadline=10)
return response.status_code
except:
return 404
如果发送成功,response.status_code会是202,这表示hub服务器接受了这个请求,但是还没验证。如果采用同步验证方式,status_code则是204,这表示验证成功。注意我用memcache来保存verify_token,你想保存到数据库里也行,反正它只用几秒而已。
此外,这步实际上不需要自己来编写代码,pubsubhubbub.appspot.com已经提供了一个Subscribe表单,直接在那提交也行。
第二步就更简单了,只要验证是否是你的请求,然后把hub.challenge参数输出,并返回200状态即可:
class VerifySubscription(yui.RequestHandler):
def get(self):
if self.GET['hub.verify_token'] == memcache.get('hub_verify_token'):
memcache.delete('hub_verify_token')
self.write(self.GET['hub.challenge'])
mail.send_mail_to_admins(ADMIN_EMAIL, u'PubSubHubbub请求验证成功', u'验证参数为:%s' % dict(self.GET))
订阅完成后就只剩下等待了。一旦你订阅的feed更新,hub服务器就会发送post请求到你的callback地址,而请求体(对webob来说就是self.request.body对象)就是更新的ATOM信息。
如果你不知道怎么处理它的话,可以试试用feedparser来解析。
向下滚动可载入更多评论,或者点这里禁止自动加载。