123456789_123456789_123456789_123456789_123456789_

Class: ActionCable::Connection::Subscriptions

Do not use. This class is for internal use only.

Overview

Collection class for all the channel subscriptions established on a given connection. Responsible for routing incoming commands that arrive on the connection to the proper channel.

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(connection) ⇒ Subscriptions

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 53

def initialize(connection)
  @connection = connection
  @subscriptions = {}
end

Instance Attribute Details

#connection (readonly, private)

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 114

attr_reader :connection, :subscriptions

#logger (readonly)

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 115

delegate :logger, to: :connection

#subscriptions (readonly, private)

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 114

attr_reader :connection, :subscriptions

Instance Method Details

#add(data)

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 68

def add(data)
  id_key = data["identifier"]

  raise MalformedCommandError, data unless id_key.present?

  raise AlreadySubscribedError, id_key if subscriptions.key?(id_key)

  subscription = subscription_from_identifier(id_key)

  if subscription
    subscriptions[id_key] = subscription
    subscription.subscribe_to_channel
  else
    id_options = ActiveSupport::JSON.decode(id_key).with_indifferent_access
    raise ChannelNotFound, id_options[:channel]
  end
end

#execute_command(data)

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 58

def execute_command(data)
  case data["command"]
  when "subscribe"   then add data
  when "unsubscribe" then remove data
  when "message"     then perform_action data
  else
    raise UnknownCommandError, data["command"]
  end
end

#find(data) (private)

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 117

def find(data)
  subscriptions[data["identifier"]]
end

#identifiers

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 105

def identifiers
  subscriptions.keys
end

#perform_action(data)

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 99

def perform_action(data)
  subscription = find(data)
  raise UnknownSubscription.new(data["identifier"]) unless subscription
  subscription.perform_action ActiveSupport::JSON.decode(data["data"])
end

#remove(data)

Raises:

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 86

def remove(data)
  raise MissingIdentifier unless data["identifier"].present?

  logger.info "Unsubscribing from channel: #{data['identifier']}"
  subscription = find(data)
  remove_subscription(subscription) if subscription
end

#remove_subscription(subscription)

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 94

def remove_subscription(subscription)
  subscription.unsubscribe_from_channel
  subscriptions.delete(subscription.identifier)
end

#subscription_from_identifier(id_key) (private)

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 121

def subscription_from_identifier(id_key)
  id_options = ActiveSupport::JSON.decode(id_key).with_indifferent_access
  subscription_klass = id_options[:channel].safe_constantize

  if subscription_klass && ActionCable::Channel::Base > subscription_klass
    subscription_klass.new(connection, id_key, id_options)
  end
end

#unsubscribe_from_all

[ GitHub ]

  
# File 'actioncable/lib/action_cable/connection/subscriptions.rb', line 109

def unsubscribe_from_all
  subscriptions.each { |id, channel| remove_subscription(channel) }
end