For example, in https://www.youtube.com/watch?v=n0WUjGkDFS0 at 10:36 he mentions the ability to create multiple channels, but how would one actually accomplish this?
According to Rails 5 ActionCable establish stream from URL parameters a variable can be defined and passed as a parameter like:
def subscribed
stream_from "room_channel_#{params[:roomId]}"
end
But in the javascript file prior to passing the data here, how does one pass in the data from the page? The following example renders an error as presumably the cable is defined before the document is loaded.
App.room = App.cable.subscriptions.create { channel: "RoomChannel", roomId: document.getElementById("message_text").getAttribute("data-room")}
Then, if one does successful get the data from the document into the variable here and passes it to the stream_from method, then lastly, how does the right channel get passed into the perform method to be used in the broadcast job?
def perform(message)
ActionCable.server.broadcast 'room_channel_???', message: render_message(message) #, roomId: roomId
end
Thanks!
I learned a lot by looking to the ActionCable example. I too was confused by the docs that suggest parsing parameters and start streaming immediately on subscription. While this is an option, you might prefer the approach below.
Create a special method that can be called from the client (JS) side, something like 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
With this code (and restart of the server) you can now call the following line when you actually have loaded the room:
App.roomChannel.perform("start_listening", {room_id: 20});
Now you can stream data for the room anywhere using broadcast_to
. E.g. from a RoomMessage after_safe
-action:
RoomChannel.broadcast_to(room, room_message)
This will broadcast the message to all who're listening.
By separating the moment you start to listen to a stream from actually opening the connection makes it easier to set up multiple data streams (There is one connection that can have many channels that can have many streams) (just don't close the old streams when starting a new one ;) ). Connection setup time is also be a bit quicker, although it typically comes at a price of having an opened connection maybe already as soon as a user signs in, something you could easily work around by subscribing just before you start listening.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With