2016-04-22 14 views
5

Ad esempio, in https://www.youtube.com/watch?v=n0WUjGkDFS0 alle 10:36 accenna alla possibilità di creare più canali, ma come si può effettivamente realizzare ciò?Come si creano più canali con Actioncable; come si passa una variabile nel documento ai canali e ai lavori di javascript e ruby?

Secondo Rails 5 ActionCable establish stream from URL parameters una variabile può essere definito e passato come parametro del tipo:

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

Ma nel file javascript prima di passare i dati qui, come si fa a passare nei dati dalla pagina? L'esempio seguente restituisce un errore poiché presumibilmente il cavo viene definito prima del caricamento del documento.

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

Quindi, se si fa successo ottenere i dati dal documento nella variabile qui e passa al metodo stream_from, poi infine, come fa il canale destro viene passato al metodo eseguire da utilizzare nella trasmissione di lavoro?

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

Grazie!

+0

Ho lo stesso problema, hai capito? –

+0

Non sono sicuro del motivo per cui non l'ho visto prima, ho risposto a una domanda simile qui che include il passaggio delle variabili: http://stackoverflow.com/questions/36926816/actioncable-how-to-use-dynamic-channels/36964252? noredirect = 1 # comment64180916_36964252 – Laser

risposta

2

Ho imparato molto guardando allo ActionCable example. Anch'io sono stato confuso dai documenti che suggeriscono parametri di analisi e avviare lo streaming immediatamente in abbonamento. Mentre this is an option, potresti preferire l'approccio in basso.

Creare un metodo speciale che può essere chiamato dal (JS) lato client, qualcosa come 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 

Con questo codice (e il riavvio del server) ora è possibile chiamare la seguente riga quando si in realtà hanno caricato la stanza:

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

Ora è possibile eseguire lo streaming dei dati per la camera ovunque utilizzando broadcast_to. Per esempio. da un RoomMessage after_safe -action:

RoomChannel.broadcast_to(room, room_message) 

Questa trasmetterà il messaggio a tutti coloro che stanno ascoltando.

Separando il momento in cui si inizia ad ascoltare uno streaming dall'effettiva apertura della connessione, è più facile impostare più flussi di dati (c'è una connessione che può avere molti canali che possono avere molti flussi) chiudere i vecchi flussi quando si avvia uno nuovo;)). Anche il tempo di impostazione della connessione è un po 'più veloce, anche se in genere ha un prezzo di avere una connessione aperta già non appena l'utente effettua l'accesso, qualcosa che potresti facilmente aggirare sottoscrivendo appena prima di iniziare ad ascoltare.

0

Mi sono inventato 2 soluzioni a questo problema.

  1. Questo è un po 'stupido: è possibile analizzare solo l'URL. Si desidera sempre la parte dopo "/", quindi grazie a REST questa opzione è valida.
  2. Migliore: è possibile includere tutto il codice di abbonamento del client in una funzione chiamata caricamento del documento. In questo modo hai tutti i dati della pagina disponibili da utilizzare per creare un nuovo abbonamento.

Spero che risponda se trovi una soluzione più pulita.

Problemi correlati