关于向用户使用ActionController :: Live和流式传输通知,我有几个问题。
我有一个我的操作可以订阅的用户通知类。在我的用户控制器的创建操作中,我告诉通知类广播新用户。
为了促进这一点,我不得不打开流。我也不知道何时取消订阅用户通知程序,因为我不知道流何时关闭(通过浏览器启动它)。
#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(...)
...
答案 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