1

我正在尝试订阅 superfeedr 上的 pubsubhubbub (pshb) 提要。pshb 协议的工作方式是

  1. 您向中心发送 POST 请求订阅提要并提供回调
  2. 集线器向您的回调发送 GET 以验证您的订阅意图
  3. 你回答说是的,我确实想订阅
  4. 集线器以订阅验证响应

我在我的开发机器上本地运行服务器。我有可以成功订阅提要的代码,我通过直接在 rails 控制台中执行它来测试它。我现在创建了一个 Feed ActiveRecord 模型,并希望在每次创建新的 Feed 记录时自动订阅。我在 Feed 模型中添加了一个 ActiveRecord 回调

after_create :subscribe_feed

现在,当我创建一个活动记录时,我看到正确的 HTTP 请求发出,然后出现长时间挂起(大约 5 秒,日志中没有任何反应),然后来自 pshb 服务器的响应说我的回调无法到达.

这是日志(我添加的数字作为参考点)

(1)   (0.1ms)  begin transaction
(2)  SQL (4.4ms)  INSERT INTO "feeds" ("created_at", "updated_at", "url") VALUES (?, ?, ?)  [["created_at", Fri, 15 Nov 2013 23:08:39 UTC +00:00], ["updated_at", Fri, 15 Nov 2013 23:08:39 UTC +00:00], ["url", "http://push-pub.appspot.com/feed"]]

(3) pshb subscribe parameters: {:headers=>{"Accept"=>"application/json"}, :body=>{"hub.mode"=>"subscribe", "hub.verify"=>"sync", "hub.callback"=>"http://...myserver.../pub_sub/callback", "hub.topic"=>"http://push-pub.appspot.com/feed", "hub.verify_token"=>"superfeedtest", "format"=>"json"}}

(4) # ABOUT 5 SECOND WAIT

(5) Subscribe Response: #<HTTParty::Response:0x7fd2180cd978 parsed_response="Your callback couldn't be reached.\n", @response=#<Net::HTTPUnprocessableEntity 422 Unprocessable Entity readbody=true>, @headers={"server"=>["nginx/0.8.52"], "date"=>["Fri, 15 Nov 2013 23:08:44 GMT"], "content-type"=>["text/plain; charset=utf-8"], "connection"=>["close"], "status"=>["422 Unprocessable Entity"], "x-runtime"=>["10057"], "content-length"=>["35"], "set-cookie"=>["_superfeedr_session=BAh7BzoMdXNlcl9pZGkC%2BIY6D3Nlc3Npb25faWQiJTBiMDExZGYzNzU4Mjk0MTMxNjc4NmE0OTg3MDhlMjJk--85d29756ae4b5ae9464630741372af7656f3894b; path=/; HttpOnly"], "cache-control"=>["no-cache"], "pubsubhubbub-version"=>["0.3"]}>

(6)   (7.2ms)  commit transaction
Redirected to http://67.180.177.165/feeds/28
Completed 302 Found in 10695ms (ActiveRecord: 11.6ms)

(7) Started GET "/pub_sub/callback?hub.challenge=437c4b3b47aa1dbf4072a2d8abb5c39a&hub.lease_seconds=315360000&hub.mode=subscribe&hub.topic=http%3A%2F%2Fpush-pub.appspot.com%2Ffeed&hub.verify_token=superfeedtest" for 173.255.193.75 at 2013-11-15 15:08:50 -0800

您可以看到在响应之后提交事务发生(6),然后来自 phsb 服务器要求验证的 GET 进入(7)。所以集线器可以到达我的回调,但由于某种原因,直到超时后我才从集线器收到 GET?

我是 Rails 新手,所以不确定事情是如何工作的,但我猜想在 ActiveRecord 创建过程中并发请求会发生一些事情。订阅独立工作,但不是在 ActiveRecord 创建期间,因为我在 after_create 中设置了它。

如果要在创建 ActiveRecord 条目时处理对 3rd 方服务器的 HTTP 请求,正确的方法是什么?

注意** 在 superfeedr api 中,您可以指定异步发生的验证意图。当我将其指定为异步时,我确实得到了成功响应,但订阅似乎仍然没有在 superfeedr 的集线器上被装箱。我将就这个问题直接联系 superfeedr,但总的来说,我想知道如何为没有异步选项的 API 处理这种情况。

4

1 回答 1

0

这个问题是 Rails 在“开发”环境中的一个众所周知的问题,它只允许一个并发的 HTTP 请求。由于您after_create :subscribe_feed在一个 HTTP 请求期间执行您的请求,因此当 Superfeedr 尝试验证您的意图时,它将在第一个请求期间向您的输入发出第二个请求 。验证将挂起,直到订阅请求完成......触发某种死锁。

解决方法很简单:hub.verify=async订阅时使用参数,Superfeedr 会先关闭订阅请求(状态为 202),然后发出意图验证。

您也可以删除hub.verify参数,因为默认情况下它是异步的。

于 2013-12-27T23:29:07.327 回答