【问题标题】:How to subscribe to a channel after page load - ActionCable, DelayedJob如何在页面加载后订阅频道 - ActionCable、DelayedJob
【发布时间】:2016-07-26 19:25:41
【问题描述】:

我有一个带有后台作业的控制器来启动 ActionCable 订阅:

  def result
    LinkBroadcastJob.perform_later(links)
  end

它执行此操作以流式传输链接:

  def perform(links)
      links.each do |link|
          ActionCable.server.broadcast "link_channel", html: render_link(link)
      end
  end

我在布局中有一个 div id="here" 的视图。

在我的文件 javascript/channes/link.coffee.js 中,它应该将所有链接附加到 div。

  App.link = App.cable.subscriptions.create { channel: "LinkChannel" },
    received: (data) ->
        $("#here").append(data.html)

此代码的问题是订阅在页面完全加载之前开始 - 因此第一个链接没有显示并且丢失。

我可以通过一些设定时间(5 秒)的延迟作业来解决它,但这不是最好的体验,而且我不知道用户加载整个页面需要多快。在创建订阅之前,我也尝试使用 $(document).load 但它不起作用。

加载 div 标签后执行订阅的最佳方式是什么?

【问题讨论】:

    标签: javascript ruby-on-rails delayed-job ruby-on-rails-5 actioncable


    【解决方案1】:

    你应该把你的客户端代码放在turbolinks:load

    jQuery(document).on 'turbolinks:load', ->
       App.link = App.cable.subscriptions.create { channel: "LinkChannel" },
         received: (data) ->
             $("#here").append(data.html)
    

    【讨论】:

    • 这是否有助于确保订阅在收到广播时正在收听?我遇到了类似的问题,当我导航到新路线时开始后台作业,后台作业在页面/js 加载并准备好接收消息之前广播。
    • 不,我认为不会。 确保它的最佳方式是从客户端发送请求。此外,如果您的后台作业在客户端渲染之前完成,最好进行同步调用并使用服务器响应发送数据
    • 这是有道理的。就我而言,我认为向客户端发出请求是最有意义的,因为这项工作可能需要长达 5 分钟。但我同意,如果它始终如一地那么快,同步完成工作会更好。
    【解决方案2】:

    我遇到了同样的问题。我建议不要使用 ...

    Query(document).on 'turbolinks:load', ->

    ...因为这已经在启动时完成了。这是我为解决这个问题所做的:

    回到你的 javascript/channes/link.coffee.js... ...实际上,将其重命名为 javascripts/channels/link.coffee (-_^)

    您有一个recieved: 方法,如下所示:

    App.link = App.cable.subscriptions.create "LinkChannel",
      received: (data) ->
          $("#here").append(data.html)
    

    虽然你没有提到它,但你应该有一种方法可以将消息/请求广播到服务器。我们暂时称它为refresh:,假设当我调用refresh: 时,这最终会将您的代码广播回客户端,在那里将调用received: 来获取您的新数据:

    App.link = App.cable.subscriptions.create "LinkChannel",
      received: (data) ->
          $("#here").append(data.html)
    
      refresh: ->
        @perform 'refresh'
    

    现在,recieved: 是一个回调,但这里还有两个有用的。这些是connected:disconnected:。当通道分别连接断开时调用它们。让我们将其添加到代码中:

    App.link = App.cable.subscriptions.create "LinkChannel",
      connected: ->
        # Called when the subscription is ready for use on the server
    
      disconnected: ->
        # Called when the subscription has been terminated by the server
    
      received: (data) ->
          $("#here").append(data.html)
    
      refresh: ->
        @perform 'refresh'
    

    现在准备好了,我们将在启动时加载您的代码。

    因此,我们将在通道 ....连接后调用 refresh: 方法,而不是使用 jQuery(document).on 'turbolinks:load', -> 作为包装器或任何其他方式。

    App.link = App.cable.subscriptions.create "LinkChannel",
      connected: ->
        App.link.refresh()
    
      disconnected: ->
        # Called when the subscription has been terminated by the server
    
      received: (data) ->
          $("#here").append(data.html)
    
      refresh: ->
        @perform 'refresh'
    

    如果您有任何问题或疑虑,请随时提问:)

    【讨论】:

      猜你喜欢
      • 2020-12-12
      • 1970-01-01
      • 2018-01-06
      • 2019-03-19
      • 1970-01-01
      • 2020-07-21
      • 2020-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多