我在Rails项目中有一个Sinatra类。它使用eventmachine和async_sinatra对外部站点进行异步调用。我想写一个会话对象(理想情况下,与Rails使用的对象相同),但到目前为止我只能:
当我进行异步调用时,用async_sinatra代码编写的会话不会被推送到客户端计算机。我怀疑其中有两件事正在发生:
标头已经发送到客户端,存储会话的本地变量(在Sinatra中)将在操作结束时被刷新。客户端永远不会看到来自服务器的请求将此数据保存到cookie。
标题是被发送到客户端,但Rails立即发送另一个,指示客户端写入cookie在其session
变量中存储的内容,覆盖西纳特拉写的是什么。
无论哪种方式,我都想在Sinatra和Rails中获得简单的会话功能。我正在做错的解释也很好:)
代码的完整工作副本是on github,但我相信此问题特别在此代码中:
class ExternalCall < Sinatra::Base
use ActionDispatch::Session::CookieStore
register Sinatra::Async
get '/sinatra/local' do
session[:demo] = "sinatra can write to Rails' session"
end
aget '/sinatra/goog' do
session[:async_call]="async sinatra calls cannot write to Rails' session"
make_async_req :get, "http://www.google.com/" do |http_callback|
if http_callback
session[:em_callback] = "this also isn't saving for me"
else
headers 'Status' => '422'
end
async_schedule { redirect '/' }
end
end
helpers do
def make_async_req(method, host, opts={}, &block)
opts[:head] = { 'Accept' => 'text/html', 'Connection' => 'keep-alive' }
http = EM::HttpRequest.new(host)
http = http.send(method, {:head => opts[:head], :body => {}, :query => {}})
http.callback &block
end
end
end
编辑7/15 :
更改Github上的代码以包含Async-Rack。 Async-sinatra可以在与Rails共享不时写入会话。比较master
和segmented_sessions
分支的行为差异。 (或在master
分支上,将use ActionDispatch::Session::CookieStore
更改为enable :sessions
)
答案 0 :(得分:1)
这是因为async_sinatra
默认使用throw :async
,有效地跳过会话中间件逻辑来存储东西。您可以像这样覆盖async_response:
helpers do
def async_response
[-1, {}, []]
end
end