我正在构建一个使用Twilio的应用程序,我们需要在调用开始后的一段时间内调用Twilio的服务器。
我正在使用RoR,现在它在Heroku上,但如果需要,我们可以将它移到其他地方。
我已经看过了延迟工作和Cron工作,但是我不知道应该走哪条路。
似乎延迟的作业和cron作业通常是重复出现的(不是很准确的计时),并且是由rake启动的,而不是由用户操作,对吗?
对于这个用例,什么工具可以给我精确的数据?
这里是《Twilio Evangelist》
我喜欢用Redis支持的worker队列来解决这个问题。Redis是一个键值存储,我们可以使用Resque(发音为"rescue")和Resque- scheduler来提供排队机制。例如,我们可以让应用程序通过使用Twilio REST API创建调用来响应用户交互。然后,我们可以将一个工作任务排在队列中,该任务将在指定的时间之后处理调用。在这里,我将在几秒钟后获得调用的状态(而不是在调用完成时等待状态回调)。
Heroku有一个关于使用Resque的非常好的演练,还有一个关于Resque with Rails的优秀Rails cast章节。Heroku提供了一个名为Redis Cloud的数据附加组件来提供Redis服务器。虽然为了开发,我在我的计算机上运行了一个本地服务器。
我基于Heroku教程和Rails cast章节创建了一个简单的应用程序。它只有一个控制器和一个模型。我正在使用模型上的回调来创建一个出站Twilio呼叫。这样,当创建新的Call
记录时,我们启动出站Twilio调用:
class Call < ActiveRecord::Base
# Twilio functionality is in a concern...
include TwilioDialable
after_create do |call|
call.call_sid = initiate_outbound call.to,
call.from,
"http://example.com/controller/action"
call.save
call
end
end
我使用一个关注来启动调用,因为我可能想从我的应用程序中的许多不同的地方做:
module TwilioDialable
extend ActiveSupport::Concern
include Twilio::REST
def initiate_outbound to, from, url
client = Twilio::REST::Client.new ENV['TW_SID'], ENV['TW_TOKEN']
client.account.calls.create(to: to, from: from, url: url).sid
end
end
这只是创建出站Twilio调用,并返回调用SID,以便我可以更新我的模型。
现在调用已经发出,所以我想检查它的状态。但由于我们希望电话先响一点,我们将在15秒后检查。在我的控制器中,我使用来自Resque-Scheduler的Resque.enqueue_in
方法来为我管理定时:
Resque.enqueue_in(15.seconds, MessageWorker, :call => @call.id)
指示Resque在执行任务之前等待15秒。它期望调用一个名为MessageWorker
的救援工人类,并将传递一个带有参数的散列:{:call => @call.id}
。为了确保这能准时发生,我将RESQUE_SCHEDULER_INTERVAL
设置为0.1秒,所以它会非常精确。MessageWorker
本身相当简单,它查找呼叫记录并使用call SID获取更新的状态并将其保存到数据库:
class MessageWorker
@queue = :message_queue
def self.perform params
# Get the call ID to do some work with...
call = Call.find(params["call"])
# Setup a Twilio Client Helper with credentials form the Environment...
client = Twilio::REST::Client.new ENV['TW_SID'], ENV['TW_TOKEN']
# We could get some
status = client.account.calls.get(call.call_sid).status
# Update my call object.
call.status = status
end
end
当我在本地运行这个时,我必须启动Redis服务器,Redis Worker rake任务,Redis Schedule rake任务,我使用Foreman和Unicorn来运行Rails应用程序。你可以将所有这些配置到你的Procfile中,以便在Heroku上运行。关于Heroku的教程是一个很好的设置演练。
但是现在我可以创建一个呼叫并让它拨出到一个电话。同时,我可以刷新calls/show/:id
页面,并在工作进程运行15秒后看到该值神奇地更新。
我还发现resque-web
对于调试Resque非常有用,因为它可以很容易地看到任务发生了什么。
希望这对你有帮助!