Rails 4直播+基于订阅的更新

时间:2013-07-07 13:37:36

标签: ruby-on-rails ruby-on-rails-4 live-streaming

关于向用户使用ActionController :: Live和流式传输通知,我有几个问题。

  1. 有没有办法判断流是否关闭或不再可写?
  2. 是否有理由在您的操作中手动关闭流?我已经看到了一些他们会明确关闭他们的流的例子,但看着浏览器,似乎它为我处理了这个?
  3. 我有一个我的操作可以订阅的用户通知类。在我的用户控制器的创建操作中,我告诉通知类广播新用户。

    为了促进这一点,我不得不打开流。我也不知道何时取消订阅用户通知程序,因为我不知道流何时关闭(通过浏览器启动它)。

    #EventsController
    def users
        response.headers['Content-Type'] = 'text/event-stream'
        sse = SSE.new(response.stream)
        sse.write({}, event: :init)
        UserNotifier.sub { |user| sse.write({ name: user.name, id: user.id }, event: :new_user ) }
      end
    

    所以这只是让一个持久的连接打开,然后一旦某个东西触发UserNotifier上的广播消息,任何一个附加到它的人将会触发它的块。

    唯一的问题是,我不知道何时取消订阅,在我的块中你看到我只是显式调用sse.write(包装响应流),而后者又盲目地调用stream.write而不知道它的状态

    更新

    我注意到有些人拯救了一个IOError异常,以此来判断客户端何时断开连接。这真的是最好的方式吗?

    rescue IOError
        UserNotifier.unsub(...)
    
    ...
    

1 个答案:

答案 0 :(得分:0)

您可以使用ensure确保在写入失败或连接已关闭或出现问题之后关闭您的信息流:

def your_action
  response.headers['Content-Type'] = 'text/event-stream'

  begin
    # Do your writing here: response.stream.write("data: ...\n\n")
  rescue IOError
    # When the client disconnects, writing will fail, throwing an IOError
  ensure
    response.stream.close
  end
end