如何检查Turbo Rails中广播频道是否存在订阅?
问题:如何检查Turbo Stream频道是否有订阅者再执行耗时操作?
在我的Rails视图中,我使用turbo_stream_from订阅Turbo Stream广播以展示患者列表:
<%= turbo_stream_from :all_patients %>
我希望在创建新患者时更新该列表,因此调用以下代码:
constly_method Turbo::StreamsChannel.broadcast_update_to(:all_patients,...)
但由于这段代码会消耗计算资源,我希望仅当当前有客户端订阅:all_patients时才执行,想要实现类似如下逻辑:
if Turbo::StreamsChannel.broadcast_subscribed?(:all_patients) constly_method Turbo::StreamsChannel.broadcast_update_to(:all_patients,...) end
请问是否有办法实现这种检查?
解决方案
Turbo本身没有提供直接的broadcast_subscribed?方法,但可以借助Action Cable的底层API实现订阅者检查:
1. 直接查询订阅集合
Action Cable会维护频道的订阅连接,你可以通过匹配流名称判断目标是否有活跃订阅者:
# 检查:all_patients流是否有订阅者 has_subscribers = Turbo::StreamsChannel.subscriptions.any? do |subscription| subscription.stream_name == "turbo_streams:all_patients" end if has_subscribers constly_method Turbo::StreamsChannel.broadcast_update_to(:all_patients, ...) end
注意:Turbo Stream的流名称固定格式为turbo_streams:[自定义流标识],必须带上前缀才能匹配。
2. 封装成自定义方法
为了复用方便,可以给Turbo::StreamsChannel添加类方法,简化调用:
# 在app/channels/turbo/streams_channel.rb中添加 class Turbo::StreamsChannel < ActionCable::Channel::Base def self.broadcast_subscribed?(stream) subscriptions.any? { |sub| sub.stream_name == "turbo_streams:#{stream}" } end end
之后就能像你最初设想的那样使用:
if Turbo::StreamsChannel.broadcast_subscribed?(:all_patients) constly_method Turbo::StreamsChannel.broadcast_update_to(:all_patients, ...) end
3. 注意事项
- 该检查是实时瞬时判断,仅反映代码执行时刻的订阅状态,后续新增的订阅者不会触发补更,适合无需回溯的场景。
- 若使用Redis作为Action Cable适配器,上述方法依然有效,
subscriptions会同步Redis中的连接状态。
内容的提问来源于stack exchange,提问作者Evgenii
相关产品推荐
相关产品推荐

