ActionCable频道订阅无效,因为频道方法未执行

时间:2017-07-26 12:06:00

标签: ruby-on-rails

我正在Rails的一家小书店工作。用户可以为单个书籍撰写评论,这些评论会添加到产品页面中。我想使用ActionCable向页面添加新评论,以便它始终保持最新状态,并在为当前位于同一页面的其他用户添加评论时显示一个小警报通知。

因此,我希望根据产品的ID为每个产品设置单独的渠道。当用户打开产品页面时,她应订阅相应的频道。

为了实现这一点,我试图调用一个名为listen的方法,只要通过在JS中调用App.product.perform('listen', {product_id: 1})加载新站点,我就会添加到ProductChannel类中。但问题是虽然调用perform,但listen永远不会被执行。我做错了什么或误解了什么?提前谢谢!

javascript/channels/prouduct.coffee的内容:

App.product = App.cable.subscriptions.create "ProductChannel",
    connected: () ->
        return

    disconnected: ->
        # Called when the subscription has been terminated by the server
        return

    received: (data) ->
        # Called when there's incoming data on the websocket for this channel
        console.log("there is data incoming so lets show the alert")
        $(".alert.alert-info").show()
        return

    listen_to_comments: ->
        @perform "listen", product_id: $("[data-product-id]").data("product-id")

$(document).on 'turbolinks:load', ->
    App.product.listen_to_comments()
    return

channels/product_channel.rb的内容:

class ProductChannel < ApplicationCable::Channel
  def subscribed
  end

  def unsubscribed
  end

  def listen(data)
    stop_all_streams
    stream_for data["product_id"]
  end
end

1 个答案:

答案 0 :(得分:0)

必须实例化连接对象:

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
      logger.add_tags current_user.name
    end

    def disconnect
      # Any cleanup work needed when the cable connection is cut.
    end

    protected
      def find_verified_user
        if current_user = User.find_by_identity cookies.signed[:identity_id]
          current_user
        else
          reject_unauthorized_connection
        end
      end
  end
end

然后你需要广播到@product

class ProductChannel < ApplicationCable::Channel
  def subscribed
    @product = Product.find(params[:product_id])
  end

  def unsubscribed
    stop_all_streams
  end

  def listen(data)
    stream_for @product
    ProductsChannel.broadcast_to(@product)
  end
end