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

Las*_*ser 5 javascript ruby-on-rails ruby-on-rails-5 actioncable

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

根据Rails 5 ActionCable从URL参数建立流,可以定义变量并将其作为参数传递,如:

  def subscribed
    stream_from "room_channel_#{params[:roomId]}"
  end
Run Code Online (Sandbox Code Playgroud)

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

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

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

  def perform(message)
    ActionCable.server.broadcast 'room_channel_???', message: render_message(message) #, roomId: roomId
  end
Run Code Online (Sandbox Code Playgroud)

谢谢!

mur*_*urb 2

通过查看ActionCable 示例,我学到了很多东西。我也对建议解析参数并在订阅时立即开始流式传输的文档感到困惑。虽然这是一个选项,但您可能更喜欢下面的方法。

创建一个可以从客户端(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
Run Code Online (Sandbox Code Playgroud)

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

App.roomChannel.perform("start_listening", {room_id: 20});
Run Code Online (Sandbox Code Playgroud)

现在,您可以使用 为房间的任何地方传输数据broadcast_to。例如,来自 RoomMessageafter_safe操作:

RoomChannel.broadcast_to(room, room_message)
Run Code Online (Sandbox Code Playgroud)

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

通过将开始侦听流的那一刻与实际打开连接的那一刻分开,可以更轻松地设置多个数据流(一个连接可以有许多通道,这些通道可以有许多流)(只是不要关闭旧流当开始新的一个时;))。连接设置时间也更快一点,尽管它通常会以用户登录后可能已经打开的连接为代价,您可以通过在开始收听之前订阅来轻松解决此问题。