ActionCable Channel示例1:用户外观。环?

时间:2017-05-25 16:00:19

标签: javascript ruby-on-rails actioncable

我目前正在努力了解ActionCable。有人可以解释一下来自官方doc的示例代码到底发生了什么:

# app/channels/appearance_channel.rb
class AppearanceChannel < ApplicationCable::Channel
  def subscribed
    current_user.appear
  end

  def unsubscribed
    current_user.disappear
  end

  def appear(data)
    current_user.appear on: data['appearing_on']
  end

  def away
    current_user.away
  end
end

与:

结合使用
# app/assets/javascripts/cable/subscriptions/appearance.coffee
App.cable.subscriptions.create "AppearanceChannel",
  # Called when the subscription is ready for use on the server
  connected: ->
    @install()
    @appear()

  # Called when the WebSocket connection is closed
  disconnected: ->
    @uninstall()

  # Called when the subscription is rejected by the server
  rejected: ->
    @uninstall()

  appear: ->
    # Calls `AppearanceChannel#appear(data)` on the server
    @perform("appear", appearing_on: $("main").data("appearing-on"))

  away: ->
    # Calls `AppearanceChannel#away` on the server
    @perform("away")


  buttonSelector = "[data-behavior~=appear_away]"

  install: ->
    $(document).on "turbolinks:load.appearance", =>
      @appear()

    $(document).on "click.appearance", buttonSelector, =>
      @away()
      false

    $(buttonSelector).show()

  uninstall: ->
    $(document).off(".appearance")
    $(buttonSelector).hide()

我不确定的是,如果current_user.appear创建了一个循环,那么告诉我用户是通过从客户端ping到服务器并返回来登录的?什么是&#39; on:&#39;在服务器端的hashtag出现功能吗? 提前谢谢。

1 个答案:

答案 0 :(得分:1)

你是正确的,因为它将是来自客户的循环 - &gt;服务器 - &gt;客户。

更详细地说,当连接到频道时,会调用@appear函数。我们可以在该函数中看到,它使用@perform来调用名为appear的服务器端函数。在此之后不幸的是它很模糊,但是我们想要向所有用户广播这个人现在在线的广告。

可能发生的一个例子是appear模型上的User函数在用户对象上设置了一个布尔值,表明它们在线,并使用on参数作为如下:

# models/user.rb
def appear(data)
  self.update(online: true, current_room: data['on'])
end

在此之后,我们需要一种让其他用户知道此人现在在线的方法。所以首先我们必须广播这个,这可能发生在更新之后(有更好的地方可以放置它但是为了解释数据流就足够了):

# models/user.rb
def appear(data)
  self.update(online: true, current_room: data['on'])
  ActionCable.server.broadcast "AppearanceChannel", {event: 'appear', user_id: self.id, room: self.current_room}
end

现在连接到Appearance Channel的所有用户都将收到数据,因此我们可以将其添加到前端。让我们说我们只想获取某种具有用户信息的div,如果他们在线,则给他们一个类online,否则删除该类:

received: (data) ->
  userId = data.user_id
  eventType = data.event
  if eventType == 'appear'
    $('#user_' + userId).addClass 'online'
  else
    $('#user_' + userId).removeClass 'online'

所以现在它将为连接到该频道的所有用户进行更新,告诉他们该用户现在已经在线。

请注意,我们没有使用用户当前所在的房间,但如果我们想要,我们可以使用data.room抓住它,并按照我们的意愿使用它。

希望有助于澄清事情。