8

Ho visto ActionCable.server.open_connections_statistics, ActionCable.server.connections.length, ActionCable.server.connections.map(&:statistics), ActionCable.server.connections.select(&:beat).count e simili, tuttavia questo è solo "per processo" (server, console, server worker, eccetera). Come faccio a trovare tutti gli utenti che sono abbonati ad ActionCable in questo momento? Questo dovrebbe restituire lo stesso valore su qualsiasi processo di Rails in ogni ambiente (sviluppo, gestione temporanea, produzione). Così, ad esempio, nella console di sviluppo è possibile vedere anche le connessioni sul server di sviluppo poiché in teoria utilizzano la stessa scheda di sottoscrizione (redis, async, postgres).Come scoprire chi è collegato ad ActionCable?

Rails 5.0.0.beta3, Ruby 2.3.0

legato ActionCable - how to display number of connected users?

risposta

13

Se si utilizza redis è possibile vedere tutti i canali PubSub.

[2] pry(main)> Redis.new.pubsub("channels", "action_cable/*") 
[ 
    [0] "action_cable/Z2lkOi8vbWFvY290LXByb2plL3QvUmVzcG9uXGVyLzEx", 
    [1] "action_cable/Z2lkOi8vbWFvY290LXByb2plL3QvUmVzcG9uXGVyLzI" 
] 

Questo mostrerà tutte le connessioni web socket per tutti i lavoratori Puma insieme. E se hai più server probabilmente mostrerà anche quelli qui.

+0

Questo è _esattamente_ quello che stavo cercando; grazie. – b264

+2

C'è un modo per differenziarli, come per camera o altri? – plombix

+0

@plombix si prega di controllare la mia risposta sotto –

3

Per essere più specifico per ActionCable (e Redis) ...

Assumendo questo canale:

class RoomChannel < ApplicationCable::Channel 
end 

Prendi l'adattatore Redis da ActionCable invece di creare da soli (avreste bisogno per fornire l'URL da config/cable.yml altrimenti):

pubsub = ActionCable.server.pubsub 

ottenere il nome del canale compreso channel_prefix yo u sia stato specificato in config/cable.yml:

channel_with_prefix = pubsub.send(:channel_with_prefix, RoomChannel.channel_name) 

ottenere tutti i canali collegati da RoomChannel:

# pubsub.send(:redis_connection) actually returns the Redis instance ActionCable uses 
channels = pubsub.send(:redis_connection). 
    pubsub('channels', "#{channel_with_prefix}:*") 

decodificare il nome di sottoscrizione:

subscriptions = channels.map do |channel| 
    Base64.decode64(channel.match(/^#{Regexp.escape(channel_with_prefix)}:(.*)$/)[1]) 
end 

Se sei iscritto a un oggetto ActiveRecord, diciamo Room (utilizzando stream_for), è possibile estrarre gli ID:

# the GID URI looks like that: gid://<app-name>/<ActiveRecordName>/<id> 
gid_uri_pattern = /^gid:\/\/.*\/#{Regexp.escape(Room.name)}\/(\d+)$/ 
chat_ids = subscriptions.map do |subscription| 
    subscription.match(gid_uri_pattern) 
    # compacting because 'subscriptions' include all subscriptions made from RoomChannel, 
    # not just subscriptions to Room records 
end.compact.map { |match| match[1] }