如何使用Actioncable创建多个频道;如何将文档内变量传递给javascript和ruby频道和作业?

时间:2016-04-22 10:17:49

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

例如,在10:36的https://www.youtube.com/watch?v=n0WUjGkDFS0中,他提到了创建多个频道的能力,但是如何实现这一目标呢?

根据Rails 5 ActionCable establish stream from URL parameters,可以定义变量并将其作为参数传递,如:

  def subscribed
    stream_from "room_channel_#{params[:roomId]}"
  end

但是在这里传递数据之前的javascript文件中,如何传递来自页面的数据?以下示例呈现错误,因为可能是在加载文档之前定义了电缆。

App.room = App.cable.subscriptions.create { channel: "RoomChannel", roomId: document.getElementById("message_text").getAttribute("data-room")}

然后,如果一个人成功将文档中的数据传入此处的变量并将其传递给stream_from方法,那么最后,如何将正确的通道传递到要在广播作业中使用的perform方法中?

  def perform(message)
    ActionCable.server.broadcast 'room_channel_???', message: render_message(message) #, roomId: roomId
  end

谢谢!

2 个答案:

答案 0 :(得分:2)

通过查看ActionCable example我学到了很多东西。我也对建议解析参数并在订阅时立即开始流式传输的文档感到困惑。在this is an option期间,您可能更喜欢以下方法。

创建一个可以从客户端(JS)调用的特殊方法,例如start_listening

class RoomChannel < ApplicationCable::Channel
  # Called when the consumer has successfully
  # become a subscriber of this channel.
  def subscribed
  end

  def start_listening room_data
    stop_all_streams # optional, you might also keep listening...
    stream_for Room.find(room_data['room_id'])
  end

  def stop_listening
    stop_all_streams
  end
end

使用此代码(并重新启动服务器),您现在可以在实际加载房间时调用以下行:

App.roomChannel.perform("start_listening", {room_id: 20});

现在,您可以使用broadcast_to在任意位置流式传输数据。例如。来自RoomMessage after_safe - 行动:

RoomChannel.broadcast_to(room, room_message)

这会将信息广播给所有正在收听的人。

通过分开你开始收听实际打开连接的流的那一刻,可以更容易地设置多个数据流(有一个连接可以有很多可以有很多流的通道)(只是不要这样做)。当开始一个新流时关闭旧流;))。连接设置时间也要快一些,虽然通常只要用户登录就可能已经打开连接,这可以在您开始收听之前通过订阅轻松解决。

答案 1 :(得分:0)

我想出了两个解决这个问题的方法。

  1. 这个有点笨 - 你可以解析URL。你总是想要在最后一个“/”之后的部分,所以多亏了REST,这是可行的选择。
  2. 更好的一个 - 您可以将所有客户订阅代码包装到文档加载调用的函数中。这样,您可以从页面中获取所有可用于创建新订阅的数据。
  3. 如果你找到一个更清洁的解决方案,希望你会回复。