2015-10-02 6 views
12

Sto provando a creare una semplice applicazione di tipo chat (pianificazione dell'app per il poker) con Action Cable. Sono un po 'confuso dalla terminologia, dalla gerarchia dei file e da come funzionano i callback.ActionCable - come visualizzare il numero di utenti connessi?

Questa è l'azione che crea sessione utente:

class SessionsController < ApplicationController 
    def create 
    cookies.signed[:username] = params[:session][:username] 
    redirect_to votes_path 
    end 
end 

Un utente può quindi inviare un voto che dovrebbe essere trasmesso a tutti:

class VotesController < ApplicationController 
    def create 
    ActionCable.server.broadcast 'poker', 
           vote: params[:vote][:body], 
           username: cookies.signed[:username] 
    head :ok 
    end 
end 

Fino a questo punto tutto è chiaro per me e funziona bene. Il problema è: come posso visualizzare il numero di utenti connessi? C'è un richiamo che si attiva in JS quando un utente (utente?) Si connette? Quello che voglio è quando apro 3 schede in 3 diversi browser in modalità in incognito che vorrei visualizzare "3". Quando un nuovo utente si connette, vorrei che il numero aumentasse. Se un utente si disconnette, il numero dovrebbe diminuire.

mio PokerChannel:

class PokerChannel < ApplicationCable::Channel 
    def subscribed 
    stream_from 'poker' 
    end 
end 

app/assets/javascripts/poker.coffee:

App.poker = App.cable.subscriptions.create 'PokerChannel', 

    received: (data) -> 
    $('#votes').append @renderMessage(data) 

    renderMessage: (data) -> 
    "<p><b>[#{data.username}]:</b> #{data.vote}</p>" 

risposta

16

Sembra che un modo è quello di utilizzare

ActionCable.server.connections.length 
+3

Si noti che questo è il numero corrente di connessione per il * thread specifico * questo è chiamato, non il numero di connessioni su vari processi e thread – edwardmp

+1

È anche il numero di connessioni al server, non a un canale specifico . – Matt

1

Per una soluzione rapida (e probabilmente non è l'ideale) è possibile scrivere un modulo che tiene traccia dei conteggi degli abbonamenti (utilizzando Redis per memorizzare i dati):

#app/lib/subscriber_tracker.rb 
module SubscriberTracker 
    #add a subscriber to a Chat rooms channel 
    def self.add_sub(room) 
    count = sub_count(room) 
    $redis.set(room, count + 1) 
    end 

    def self.remove_sub(room) 
    count = sub_count(room) 
    if count == 1 
     $redis.del(room) 
    else 
     $redis.set(room, count - 1) 
    end 
    end 

    def self.sub_count(room) 
    $redis.get(room).to_i 
    end 
end 

e aggiornare il sottoscritto e metodi non sottoscritte nella classe del canale:

class ChatRoomsChannel < ApplicationCable::Channel 
    def subscribed 
    SubscriberTracker.add_sub params['room_id'] 
    end 

    def unsubscribed 
    SubscriberTracker.remove_sub params['chat_room_id'] 
    end 
end 
1

In un relativo question on who is connected, ci fu una risposta a coloro che usa Redis:

Redis.new.pubsub("channels", "action_cable/*") 

e se vuoi solo il numero di connessioni:

Redis.new.pubsub("NUMPAT", "action_cable/*") 

In questo modo verranno riepilogate le connessioni da tutti i server.

Tutta la magia coperta all'interno della classe RemoteConnections e del modulo InternalChannel.

TL; DR tutte le connessioni sottoscritte su canali speciali con un prefisso action_cable/* con l'unico scopo di scollegare le prese dall'app principale.