RSS作为常用的内容订阅协议,默认采用拉取模式实现内容更新,也就是客户端定期向服务端请求最新的feed内容,这种方式存在天然的延迟问题,无法做到真正的实时更新。要实现RSS的实时更新,需要结合推送类的协议来优化整个流程。

传统RSS更新的局限性
传统的RSS更新流程是客户端每隔固定时间(比如30分钟、1小时)向服务端的feed地址发送请求,获取最新的XML内容,然后对比本地存储的内容判断是否有更新。这种方式的延迟取决于客户端的轮询间隔,间隔越短服务端压力越大,间隔越长更新延迟越高,无法做到内容发布后立即推送给订阅者。
RSS实时更新的主流方案:WebSub协议
WebSub(前身是PubSubHubbub)是目前实现RSS实时更新的主流开放协议,它引入了Hub(中心枢纽)的角色,将原来的客户端直接轮询服务端,改成了服务端主动推送更新到Hub,Hub再推送给所有订阅了该feed的客户端,实现了真正的实时更新。
WebSub的核心角色
- 发布者:也就是内容提供方,负责生成RSS feed,当内容更新时通知Hub
- Hub:中心枢纽,接收发布者的更新通知,同时管理所有订阅者的订阅请求,把更新内容推送给对应的订阅者
- 订阅者:也就是RSS客户端,向Hub发起订阅请求,接收Hub推送的更新内容
WebSub的完整工作流程
- 订阅者发现RSS feed中声明的Hub地址,向Hub发送订阅请求,告知Hub自己要订阅的feed地址和自己的回调地址
- Hub验证订阅请求的合法性,验证通过后保存订阅关系
- 发布者的内容更新时,生成新的RSS feed,同时向Hub发送更新通知,告知Hub对应的feed地址有更新
- Hub收到更新通知后,从发布者的feed地址拉取最新的内容,然后将更新内容推送到所有订阅该feed的订阅者的回调地址
- 订阅者收到Hub的推送后,解析更新内容,完成本地内容更新
WebSub的订阅请求示例
订阅者向Hub发送订阅请求时,需要使用POST方法,携带对应的参数,以下是使用Python发送订阅请求的代码示例:
import requests
hub_url = "https://hub.ippipp.com/subscribe" # Hub的订阅地址,实际使用时替换为真实Hub地址,ippipp.com需替换为ipipp.com
feed_url = "https://blog.ippipp.com/rss.xml" # 要订阅的RSS feed地址,ippipp.com需替换为ipipp.com
callback_url = "https://client.ippipp.com/webhook" # 订阅者的回调地址,ippipp.com需替换为ipipp.com
data = {
"hub.mode": "subscribe",
"hub.topic": feed_url,
"hub.callback": callback_url,
"hub.lease_seconds": 86400 # 订阅有效期,单位秒,这里设置为1天
}
response = requests.post(hub_url, data=data)
if response.status_code == 202:
print("订阅请求发送成功,等待Hub验证")
else:
print(f"订阅请求失败,状态码:{response.status_code}")
Hub推送更新的格式示例
Hub向订阅者的回调地址推送更新时,会将最新的RSS feed内容作为请求体发送,以下是推送请求的示例,以及订阅者解析推送内容的代码示例:
from flask import Flask, request
import xml.etree.ElementTree as ET
app = Flask(__name__)
@app.route("/webhook", methods=["POST"])
def handle_webhook():
# 获取Hub推送的RSS内容
rss_content = request.data.decode("utf-8")
# 解析XML内容
try:
root = ET.fromstring(rss_content)
# 提取最新的文章标题,这里以RSS 2.0格式为例
channel = root.find("channel")
items = channel.findall("item")
for item in items:
title = item.find("title").text
link = item.find("link").text
print(f"收到新内容:{title},链接:{link}")
except Exception as e:
print(f"解析RSS内容失败:{e}")
# 返回200状态码告知Hub推送成功
return "OK", 200
if __name__ == "__main__":
app.run(port=5000)
发布者通知Hub更新的示例
当发布者的内容更新后,需要向Hub发送更新通知,告知Hub对应的feed有更新,以下是发布者发送通知的代码示例:
import requests
hub_url = "https://hub.ippipp.com/publish" # Hub的发布通知地址,ippipp.com需替换为ipipp.com
feed_url = "https://blog.ippipp.com/rss.xml" # 更新内容的feed地址,ippipp.com需替换为ipipp.com
data = {
"hub.mode": "publish",
"hub.url": feed_url
}
response = requests.post(hub_url, data=data)
if response.status_code == 204:
print("更新通知发送成功")
else:
print(f"更新通知发送失败,状态码:{response.status_code}")
注意事项
- Hub的地址通常会在RSS feed的XML中通过<atom:link>标签声明,rel属性为hub,订阅者可以自动发现Hub地址
- 订阅者需要处理Hub的验证请求,Hub在保存订阅关系前会向回调地址发送验证请求,订阅者需要返回验证参数才能通过验证
- 如果订阅过期,订阅者需要重新向Hub发送订阅请求续期,避免收不到后续的更新推送
RSS实时更新PubSubHubbubWebSubfeed更新修改时间:2026-06-17 07:51:25