У меня есть класс Sinatra в проекте Rails.Он использует eventmachine и async_sinatra для выполнения асинхронных вызовов на внешние сайты.Я хотел бы записать в объект сеанса (в идеале, тот же, который использует Rails), но пока я могу только:
- писать в отдельный объект сеанса из Rails '(по умолчанию)Sinatra называет свой сеанс чем-то отличным от Rails)
- запись в тот же сеанс только для только синхронные вызовы
Когда я выполняю асинхронные вызовы, сеансы записываются вКод async_sinatra не выталкивается на клиентский компьютер.Я подозреваю, что происходит одно из двух:
Заголовок уже отправлен клиенту, и локальная переменная, хранящая сеанс (в Синатре), будет сброшена в концедействие.Клиент никогда не увидит запрос от сервера на сохранение этих данных в cookie.
Заголовок отправляется клиенту , но Rails немедленно отправляет другойпоручить клиенту записать в cookie то, что Rails сохранил в его переменной session
, перезаписать то, что написал Синатра.
В любом случае, я хотел бы просто получить простую функциональность сеансав Синатре и Рельсах.Было бы неплохо объяснить, что я делаю неправильно:)
Полная рабочая копия кода на 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
)