加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 我可以在Rails 3中使用AMQP使用请求/回复 – R

发布时间:2020-12-17 03:15:23 所属栏目:百科 来源:网络整理
导读:由于类似于 this discussion中的原因,我正在尝试使用消息传递来代替REST,以便从一个Rails 3应用程序到另一个Rails 3应用程序进行同步RPC调用.这两个应用程序都在运行. “server”应用程序具有基于rubyamqp.info documentation中的请求/回复模式的config / in
由于类似于 this discussion中的原因,我正在尝试使用消息传递来代替REST,以便从一个Rails 3应用程序到另一个Rails 3应用程序进行同步RPC调用.这两个应用程序都在运行.

“server”应用程序具有基于rubyamqp.info documentation中的请求/回复模式的config / initializers / amqp.rb文件:

require "amqp"

EventMachine.next_tick do
  connection = AMQP.connect ENV['CLOUDAMQP_URL'] || 'amqp://guest:guest@localhost'
  channel    = AMQP::Channel.new(connection)

  requests_queue = channel.queue("amqpgem.examples.services.time",:exclusive => true,:auto_delete => true)
  requests_queue.subscribe(:ack => true) do |metadata,payload|
    puts "[requests] Got a request #{metadata.message_id}. Sending a reply..."
    channel.default_exchange.publish(Time.now.to_s,:routing_key    => metadata.reply_to,:correlation_id => metadata.message_id,:mandatory      => true)
    metadata.ack
  end

  Signal.trap("INT") { connection.close { EventMachine.stop } }
end

在“客户端”应用程序中,我想在视图中将同步调用的结果呈现给“服务器”.我意识到这有点像amqp gem这样的固有异步库的舒适区域,但我想知道是否有办法让它工作.这是我的客户端config / initializers / amqp.rb:

require 'amqp'

EventMachine.next_tick do
  AMQP.connection = AMQP.connect 'amqp://guest:guest@localhost'  
  Signal.trap("INT") { AMQP.connection.close { EventMachine.stop } }
end

这是控制器:

require "amqp"

class WelcomeController < ApplicationController
  def index    
    puts "[request] Sending a request..."

    WelcomeController.channel.default_exchange.publish("get.time",:routing_key => "amqpgem.examples.services.time",:message_id  => Kernel.rand(10101010).to_s,:reply_to    => WelcomeController.replies_queue.name)

    WelcomeController.replies_queue.subscribe do |metadata,payload|
      puts "[response] Response for #{metadata.correlation_id}: #{payload.inspect}"
      @message = payload.inspect
    end   
  end

  def self.channel
    @channel ||= AMQP::Channel.new(AMQP.connection)
  end

  def self.replies_queue
    @replies_queue ||= channel.queue("reply",:auto_delete => true)
  end
end

当我在不同的端口上启动两个应用程序并访问welcome #index视图时.
@message在视图中为零,因为结果尚未返回.结果在渲染视图后几毫秒到达并显示在控制台上:

$thin start
>> Using rack adapter
>> Thin web server (v1.5.0 codename Knife)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:3000,CTRL+C to stop
[request] Sending a request...
[response] Response for 3877031: "2012-11-27 22:04:28 -0600"

这里不足为奇:subscribe显然不适用于同步调用.令人惊讶的是,我无法在AMQP gem源代码或任何在线文档中找到同步替代方案.是否有订阅的替代方法可以提供我想要的RPC行为?鉴于系统的其他部分我想要使用合法的异步调用,bunny gem似乎不适合这项工作.我应该再看一眼吗?

编辑以响应Sam Stokes

感谢Sam提供的抛出指针:async / async.callback.我之前没有见过这种技术,这正是我首先尝试用这个实验学习的东西. send_response.finish在Rails 3中消失了,但是我能够通过一个小的改动让他的例子至少为一个请求工作:

render :text => @message
rendered_response = response.prepare!

后续请求失败!!处理请求时出现意外错误:死锁;递归锁定.这可能是Sam在获取有关获取ActionController以允许并发请求的注释时所得到的,但引用的gist仅适用于Rails 2.在development.rb中添加config.allow_concurrency = true可以在Rails 3中消除此错误,但是导致此队列已具有默认使用者.来自AMQP.

我觉得这只牦牛已经剃光了.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读