我正在构建一个使用Twilio的应用程序,我们需要在通话开始后的一段时间内调用Twilio的服务器。
我正在使用RoR,现在正在使用Heroku,但如果需要,我们可以将它移到别处。
我看过延迟工作和Cron工作,但我不知道应该知道应该走哪条路。
似乎延迟作业和cron作业通常会重复发生(时间不是很准确),并且不是通过用户操作而是以rake开头,对吗?
什么工具会让我对这个用例有一定的准确性?
答案 0 :(得分:1)
Twilio Evangelist在这里。
我喜欢用Redis支持的工作队列来解决这个问题。 Redis是一个键值存储,我们可以使用Resque(发音为'rescue')和Resque-Scheduler来提供排队机制。例如,我们可以让应用程序通过使用Twilio REST API创建呼叫来响应用户交互。然后,我们可以将一个工作任务排队,该任务将在稍后的指定时间内对该调用执行某些操作。在这里,我只是在几秒钟之后得到呼叫的状态(而不是在呼叫完成时等待status callback)。
Heroku在使用Resque时有很好的演练,在Resque with Rails上也有一个很棒的Rails Casts episode。 Heroku提供了一个名为data add-on的Reddis Cloud来提供Redis服务器。虽然对于开发我在我的计算机上运行本地服务器。
我基于Heroku教程和Rails Casts剧集创建了一个简单的应用程序。它有一个控制器和一个模型。我在模型上使用callback来创建出站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
的Resque工作类,并将传递带参数的哈希:{: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上运行。 tutorial on Heroku是进行此设置的绝佳演练。
但是现在我可以创建一个电话并让它拨打电话。与此同时,我可以刷新calls/show/:id
页面,并在15秒后运行工作进程时看到神奇更新的值。
我还发现resque-web
对于调试Resque非常有用,因为它可以很容易地看到你的任务发生了什么。
希望这有帮助!