Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何在rails中发出异步http请求_Ruby_Http_Ruby On Rails 4_Asynchronous - Fatal编程技术网

Ruby 如何在rails中发出异步http请求

Ruby 如何在rails中发出异步http请求,ruby,http,ruby-on-rails-4,asynchronous,Ruby,Http,Ruby On Rails 4,Asynchronous,在我的rails应用程序中,我需要向第三方服务发出http请求,因为http请求是同步的,有时需要20秒以上才能从他们那里得到响应 我只是将一些数据推送到该服务,我不关心响应是什么,所以我希望使请求异步,这样我的代码将继续执行而不会被阻塞 我如何在ruby中做到这一点?您需要在ruby中使用事件机和光纤 我需要发出http请求…这样我的代码将继续执行而不会被阻止 下面是一个sinatra应用程序,您可以使用它进行测试: 1) $gem安装sinatra (二) 输出: $ ruby my_si

在我的rails应用程序中,我需要向第三方服务发出http请求,因为http请求是同步的,有时需要20秒以上才能从他们那里得到响应

我只是将一些数据推送到该服务,我不关心响应是什么,所以我希望使请求异步,这样我的代码将继续执行而不会被阻塞


我如何在ruby中做到这一点?

您需要在ruby中使用事件机和光纤

我需要发出http请求…这样我的代码将继续执行而不会被阻止

下面是一个sinatra应用程序,您可以使用它进行测试:

1)
$gem安装sinatra

(二)

输出

$ ruby my_sinatra_app.rb
== Sinatra (v1.4.6) has taken the stage on 4567 for development with backup from Thin
Thin web server (v1.6.4 codename Gob Bluth)
Maximum connections set to 1024
Listening on localhost:4567, CTRL+C to stop

received: {"x"=>"1", "y"=>"2"}
<20 second delay>
Sending response...

127.0.0.1 - - [11/Nov/2015:12:54:53 -0400] "POST /do_stuff HTTP/1.1" 200 18 20.0032
$ruby my\u sinatra\u app.rb
==Sinatra(v1.4.6)已在4567上登场,进行了基于精简备份的开发
瘦web服务器(v1.6.4代码名Gob Bluth)
最大连接数设置为1024
正在本地主机上侦听:4567,CTRL+C停止
收到:{“x”=>“1”,“y”=>“2”}
正在发送响应。。。
127.0.0.1--[11/Nov/2015:12:54:53-0400]“POST/do_stuff HTTP/1.1”200 18 20.0032

当您在rails应用程序中导航到
some_action()
时,rails服务器窗口将立即输出
****在收到响应之前继续执行。
,而sinatra服务器窗口将立即输出
参数
散列,其中包含post请求中发送的数据。然后,在20秒延迟后,sinatra服务器窗口将输出
发送响应…

您应该签出,我不想要队列解决方案,因为我认为对于一个简单的http请求来说,这是过度杀戮。EventMachine defer是一个好的解决方案吗?谢谢你的回答,但似乎有一个问题,因为http请求是在一个新线程中执行的,客户端立即终止,sinatra应用程序永远不会收到请求。如果我在客户机代码的末尾添加一行代码,那么它就可以工作了,你知道如何解决这个问题吗?@xiaopang,如果你写
t=Thread.new…
,然后在客户机的末尾添加
t.join
,那么客户机在线程完成执行之前不会退出。您可以以秒为单位添加一个超时:
t.join(500)
。是的,它是这样工作的,但它错过了无阻塞的全部要点,对吗?:)@小胖,我改变了我的评论。它错过了没有阻挡的关键,对吗?是的,
t.join
之前的任何代码都将在收到响应之前执行,但如果您的操作中没有其他代码,则在收到响应之前,视图将不会呈现:(@xiaopang,客户端立即终止了--你能解释一下你是怎么做的吗?你的客户端是什么?据我所知,Sinatra应用程序的客户端是你的Rails应用程序。嗨@harshit,你能详细说明一下吗?我试过事件机,但据我所知,代码执行仍然阻塞
#my_sinatra_app.rb

require 'sinatra'

post '/do_stuff' do
  puts "received: #{params}" #Check the sinatra server window for the output.
  sleep 20  #Do some time consuming task.

  puts "Sending response..."
  "The result was: 30"   #The response(which the rails app ignores).
end
$ ruby my_sinatra_app.rb
== Sinatra (v1.4.6) has taken the stage on 4567 for development with backup from Thin
Thin web server (v1.6.4 codename Gob Bluth)
Maximum connections set to 1024
Listening on localhost:4567, CTRL+C to stop

received: {"x"=>"1", "y"=>"2"}
<20 second delay>
Sending response...

127.0.0.1 - - [11/Nov/2015:12:54:53 -0400] "POST /do_stuff HTTP/1.1" 200 18 20.0032