当流媒体设置时,sinatra会话成员消失

时间:2014-10-19 22:31:46

标签: ruby sinatra rack

如果我的sinatra处理程序中有此代码:

get '/foo' do
  session[:message] = 'hello world'

  stream {|out|
    out << session[:message]
  }
end

get '/bar' do
  session[:message]
end

然后两个网址都以hello world回复(/bar后访问/foo)。如果我在stream调用中移动会话初始化代码,如下所示,那么/foo将像以前一样以hello world响应,但/bar以空字符串响应。

这是一个错误吗?如何确保当我在流媒体块中设置会话变量时,它会在其他处理程序中正确读取?

get '/foo' do
  stream {|out|
    session[:message] = 'hello world';
    out << session[:message]
  }
end

1 个答案:

答案 0 :(得分:0)

会话作为中间件。当请求进入当前会话变量(如果有)时,它们从存储它们的任何地方读入,并作为散列提供给请求的其余部分。请求完成后,中间件会将此哈希持久保存到正在使用的任何会话存储中,并在响应上设置相应的标头。 (我在这里有所简化,但这基本上就是这样)。

当流式传输时,在响应完成后,即在会话中间件运行之后,将stream的块称为。这意味着尽管session哈希仍然可用,并且您可以在其上设置项目,但它永远不会保存在任何地方,因此您在此处设置的任何内容都不会在以后的任何请求中提供。

如果您使用的是基于cookie的默认会话存储,那么除了确保将会话变量设置在stream块之外之外,您几乎无法做到这一点。在调用stream块时,所有标头都已写出,包括包含序列化会话数据的cookie。

如果您使用的是服务器端会话存储,则可以更改会话代码,以便保留这些后续更新。是否值得这将是另一个问题。