Class: ActionCable::Connection::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/anycable/rails/actioncable/connection.rb

Overview

rubocop: disable Metrics/ClassLength

Constant Summary collapse

LOG_TAGS_IDENTIFIER =

We store logger tags in identifiers to be able to re-use them in the subsequent calls

"__ltags__"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(socket, identifiers: "{}", subscriptions: []) ⇒ Base

Returns a new instance of Base.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/anycable/rails/actioncable/connection.rb', line 34

def initialize(socket, identifiers: "{}", subscriptions: [])
  @ids = ActiveSupport::JSON.decode(identifiers)

  @ltags = ids.delete(LOG_TAGS_IDENTIFIER)

  @cached_ids = {}
  @env = socket.env
  @coder = ActiveSupport::JSON
  @socket = socket
  @subscriptions = ActionCable::Connection::Subscriptions.new(self)

  # Initialize channels if any
  subscriptions.each { |id| @subscriptions.fetch(id) }
end

Instance Attribute Details

#socketObject (readonly)

Returns the value of attribute socket.



17
18
19
# File 'lib/anycable/rails/actioncable/connection.rb', line 17

def socket
  @socket
end

Class Method Details

.call(socket, **options) ⇒ Object



20
21
22
# File 'lib/anycable/rails/actioncable/connection.rb', line 20

def call(socket, **options)
  new(socket, options)
end

.identified_by(*identifiers) ⇒ Object



24
25
26
27
28
29
30
31
# File 'lib/anycable/rails/actioncable/connection.rb', line 24

def identified_by(*identifiers)
  super
  Array(identifiers).each do |identifier|
    define_method(identifier) do
      instance_variable_get(:"@#{identifier}") || fetch_identifier(identifier)
    end
  end
end

Instance Method Details

#closeObject

rubocop:enable Metrics/MethodLength



87
88
89
# File 'lib/anycable/rails/actioncable/connection.rb', line 87

def close
  socket.close
end

#fetch_identifier(name) ⇒ Object

Fetch identifier and deserialize if neccessary



113
114
115
116
117
118
119
120
# File 'lib/anycable/rails/actioncable/connection.rb', line 113

def fetch_identifier(name)
  @cached_ids[name] ||= @cached_ids.fetch(name) do
    val = ids[name.to_s]
    next val unless val.is_a?(String)

    GlobalID::Locator.locate(val) || val
  end
end

#handle_channel_command(identifier, command, data) ⇒ Object

rubocop:disable Metrics/MethodLength



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/anycable/rails/actioncable/connection.rb', line 69

def handle_channel_command(identifier, command, data)
  channel = subscriptions.fetch(identifier)
  case command
  when "subscribe"
    channel.handle_subscribe
    !channel.subscription_rejected?
  when "unsubscribe"
    subscriptions.remove_subscription(channel)
    true
  when "message"
    channel.perform_action ActiveSupport::JSON.decode(data)
    true
  else
    false
  end
end

#handle_closeObject



60
61
62
63
64
65
66
# File 'lib/anycable/rails/actioncable/connection.rb', line 60

def handle_close
  logger.info finished_request_message if access_logs?

  subscriptions.unsubscribe_from_all
  disconnect if respond_to?(:disconnect)
  true
end

#handle_openObject



49
50
51
52
53
54
55
56
57
58
# File 'lib/anycable/rails/actioncable/connection.rb', line 49

def handle_open
  logger.info started_request_message if access_logs?

  verify_origin!

  connect if respond_to?(:connect)
  send_welcome_message
rescue ActionCable::Connection::Authorization::UnauthorizedError
  reject_request
end

#identifiers_hashObject

Generate identifiers info. Converts GlobalID compatible vars to corresponding global IDs params.



97
98
99
100
101
102
103
104
105
106
# File 'lib/anycable/rails/actioncable/connection.rb', line 97

def identifiers_hash
  obj = { LOG_TAGS_IDENTIFIER => fetch_ltags }

  identifiers.each_with_object(obj) do |id, acc|
    obj = instance_variable_get("@#{id}")
    next unless obj

    acc[id] = obj.try(:to_gid_param) || obj
  end.compact
end

#identifiers_jsonObject



108
109
110
# File 'lib/anycable/rails/actioncable/connection.rb', line 108

def identifiers_json
  identifiers_hash.to_json
end

#loggerObject



122
123
124
# File 'lib/anycable/rails/actioncable/connection.rb', line 122

def logger
  @logger ||= TaggedLoggerProxy.new(AnyCable.logger, tags: ltags || [])
end

#transmit(cable_message) ⇒ Object



91
92
93
# File 'lib/anycable/rails/actioncable/connection.rb', line 91

def transmit(cable_message)
  socket.transmit encode(cable_message)
end