Sinatra Streaming Responses

2023-12-20 15:43 更新

有时候,想要在开始发送数据时依然生成一些响应体。考虑一个极端的例子,在客户端关闭连接之前,一直发送数据。可以使用流辅助方法来避免自己创建包装方法。

get '/' do
  stream do |out|
    out << "It's gonna be legen -\n"
    sleep 0.5
    out << " (wait for it) \n"
    sleep 1
    out << "- dary!\n"
  end
end

可以使用 stream 方法实现流式 API,服务器发送事件以及用作 WebSocket 的基础。该方法同样也可用来提高速度,如果只有部分内容依赖缓慢的资源。

注意:流式行为,特别是并发请求的数据,高度依赖用来提供应用的 web 服务器。有些服务器,比如 WEBRick,根本不支持流。如果服务器不支持流,当传递给流的块结束执行时,响应体将会被立即返回。流并不是包治百病的万金油。

如果可选的参数设置为​keep_open​, 不会自动对流对象调用 close 方法,而是允许在随后的执行流中手动关闭。这近对那些时间驱动的服务器 (Thin,Rainbows) 起作用,其他服务器依然会关闭流。

# long polling

set :server, :thin
connections = []

get '/subscribe' do
  # register a client's interest in server events
  stream(:keep_open) { |out| connections << out }

  # purge dead connections
  connections.reject!(&:closed?)

  # acknowledge
  "subscribed"
end

post '/message' do
  connections.each do |out|
    # notify client that a new message has arrived
    out << params[:message] << "\n"

    # indicate client to connect again
    out.close
  end

  # acknowledge
  "message received"
end


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号