5

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

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

  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

谢谢!

4

2 回答 2

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

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

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

现在,您可以使用broadcast_to. 例如来自 RoomMessage after_safe-action:

RoomChannel.broadcast_to(room, room_message)

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

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

于 2016-10-05T21:45:00.433 回答
0

我想出了2个解决这个问题的办法。

  1. 这有点愚蠢 - 你可以解析 URL。您总是想要最后一个“/”之后的部分,因此感谢 REST,这是一个可行的选择。
  2. 更好的一个 - 您可以将所有客户端订阅代码包装到在文档加载时调用的函数中。这样,您就可以将页面中的所有数据用于创建新订阅。

如果您找到更清洁的解决方案,希望您能回复。

于 2017-03-06T01:50:44.253 回答