0

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

  1. 有没有办法判断流是否/何时关闭或不再可写?
  2. 是否有理由在您的操作中手动关闭流?我看过一些他们会明确关闭他们的流的例子,但是看着浏览器,它似乎为我处理了这个?

我有一个我的操作可以订阅的用户通知类。在我的用户控制器的创建操作中,我告诉通知类广播新用户。

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

#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(...)

...
4

1 回答 1

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
于 2013-08-02T19:18:59.857 回答