В вашем контроллере при обработке SSE ожидается, что вы будете выполнять обновления в al oop, тогда ActionController::Live::ClientDisconnected
повышается на response.stream.write
после ухода клиента:
def regular_update
response.headers['Content-Type'] = 'text/event-stream'
sse = SSE.new(response.stream, event: 'notice')
loop do
sse.write(NoticeTask.perform) # custom code returning the JSOn
sleep 60
end
rescue ClientDisconnected
logger.info "Client is gone"
ensure
sse.close
end
ваш код отключает клиент после первого обновления и задержки, но все, кажется, работает, потому что EventSource
автоматически переподключается (таким образом, вы получаете длинные опросы обновлений).
На клиенте EventSource
должно быть close()
d один раз не нужен Обычно это делается автоматически при переходе от страницы, на которой он находится, поэтому:
- убедитесь, что источник событий javascript находится только на странице панели инструментов, а не в пакете javascript (или в комплекте, но включается только на указанной странице c)
- если вы используете turbolinks - вам нужно
close()
установить соединение вручную, в качестве быстрого решения - попробуйте добавить <meta name="turbolinks-visit-control" content="reload">
в заголовок страницы или временно отключить турболинки .
Также еще раз подумайте, нужен ли вам SSE для этой конкретной задачи c, потому что для простых периодических c обновлений вы можете просто опросить действие json из кода на стороне клиента, которое будет визуализировать те же данные. Это упростит контроллер, не будет держать соединение занятым для каждого клиента, будет иметь более широкую совместимость с сервером и т. Д. c.
Для обоснования SSE - по крайней мере, проверьте, действительно ли что-то изменилось, и пропустите сообщение, если ничего нет , Лучше использовать какой-нибудь pub-sub (например, Redis 'SUBSCRIBE
/ PUBLISH
или Postgres' LISTEN
/ NOTIFY
) - отправлять события в topi c каждый раз, когда что-то влияет Изменения в панели управления, подписка на SSE-соединение и т. д. (также могут быть обновления газа, зависит от вашего приложения). Подобное может быть реализовано с помощью ActionCable (немного излишне, но может быть удобно, так как уже интегрировано в pub-sub)