8

Widziałem ActionCable.server.open_connections_statistics, ActionCable.server.connections.length, ActionCable.server.connections.map(&:statistics), i tym podobne, jednak jest to tylko "za proces" (serwer, konsola, pracownik serwera itp.). Jak mogę się dowiedzieć, kto jest subskrybowany ActionCable w tej chwili? Powinno to zwrócić tę samą wartość w każdym procesie Rails w każdym środowisku (rozwój, pomosty, produkcja). Na przykład w konsoli programistycznej można również zobaczyć połączenia na serwerze programistycznym, ponieważ teoretycznie używają tego samego adaptera subskrypcji (redis, async, postgres).Jak mogę się dowiedzieć, kto jest podłączony do ActionCable?

Szyny 5.0.0.beta3, Ruby 2.3.0

związane ActionCable - how to display number of connected users?

Odpowiedz

13

przypadku korzystania redis można zobaczyć wszystkie kanały PubSub.

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

Spowoduje to wyświetlenie wszystkich połączeń internetowych dla wszystkich pracowników Puma. A jeśli masz wiele serwerów, prawdopodobnie pokaże je również tutaj.

+0

To _exactly_ czego szukałem; Dziękuję Ci. – b264

+2

Czy istnieje sposób na ich odróżnienie, na przykład w pokoju lub w innym pomieszczeniu? – plombix

+0

@plombix Proszę sprawdzić moją odpowiedź poniżej –

3

Aby być bardziej specyficzne dla ActionCable (i do Redis) ...

Zakładając ten kanał:

class RoomChannel < ApplicationCable::Channel 
end 

uzyskać adapter Redis z ActionCable zamiast tworzenia go samodzielnie (należałoby dostarczyć URL z config/cable.yml inaczej):

pubsub = ActionCable.server.pubsub 

Uzyskaj nazwę kanału w tym channel_prefix yo U mogą mieć określony w config/cable.yml:

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

Get wszystkich podłączonych kanałów z RoomChannel:

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

Decode nazwa subskrypcji:

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

Jeżeli jesteś zapisany do obiektu ActiveRecord, załóżmy, że Room (przy użyciu stream_for), możesz wyodrębnić identyfikatory:

# 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] }