Class: AnyCable::Rails::Connection
- Inherits:
-
Object
- Object
- AnyCable::Rails::Connection
- Defined in:
- lib/anycable/rails/connection.rb,
lib/anycable/rails/next/connection.rb
Defined Under Namespace
Classes: Subscriptions
Constant Summary collapse
- LOG_TAGS_IDENTIFIER =
We store logger tags in the connection state to be able to re-use them in the subsequent calls
"__ltags__"
Instance Attribute Summary collapse
-
#logger ⇒ Object
readonly
Action Cable socket interface [BEGIN].
-
#protocol ⇒ Object
readonly
Action Cable socket interface [BEGIN].
-
#server ⇒ Object
readonly
Returns the value of attribute server.
-
#socket ⇒ Object
readonly
Returns the value of attribute socket.
Instance Method Summary collapse
- #action_cable_connection ⇒ Object
- #build_rack_request(env) ⇒ Object
- #close ⇒ Object
- #handle_channel_command(identifier, command, data) ⇒ Object
- #handle_close ⇒ Object
-
#handle_open ⇒ Object
AnyCable RPC interface [BEGIN] ==.
-
#initialize(connection_class, socket, identifiers: nil, subscriptions: nil, server: ::ActionCable.server) ⇒ Connection
constructor
A new instance of Connection.
- #perform_work(receiver, method_name, *args) ⇒ Object
- #request ⇒ Object
- #transmit(data) ⇒ Object
Constructor Details
#initialize(connection_class, socket, identifiers: nil, subscriptions: nil, server: ::ActionCable.server) ⇒ Connection
Returns a new instance of Connection.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/anycable/rails/connection.rb', line 110 def initialize(connection_class, socket, identifiers: nil, subscriptions: nil) @socket = socket = @logger = ActionCable::Connection::TaggedLoggerProxy.new(AnyCable.logger, tags: ) # Instead of calling #initialize, # we allocate an instance and setup all the required components manually @conn = connection_class.allocate # Required to access config (for access origin checks) conn.server = ActionCable.server conn.logger = logger conn.anycable_socket = conn.websocket = socket conn.env = socket.env conn.coder = ActiveSupport::JSON conn.subscriptions = ActionCable::Connection::Subscriptions.new(conn) conn.serialized_ids = {} conn.serialized_ids = ActiveSupport::JSON.decode(identifiers) if identifiers conn.cached_ids = {} conn.anycable_request_builder = self # Pre-initialize channels (for disconnect) conn.subscriptions.restore(subscriptions, socket.istate) if subscriptions end |
Instance Attribute Details
#logger ⇒ Object (readonly)
Action Cable socket interface [BEGIN]
161 162 163 |
# File 'lib/anycable/rails/next/connection.rb', line 161 def logger @logger end |
#protocol ⇒ Object (readonly)
Action Cable socket interface [BEGIN]
161 162 163 |
# File 'lib/anycable/rails/next/connection.rb', line 161 def protocol @protocol end |
#server ⇒ Object (readonly)
Returns the value of attribute server.
112 113 114 |
# File 'lib/anycable/rails/next/connection.rb', line 112 def server @server end |
#socket ⇒ Object (readonly)
Returns the value of attribute socket.
108 109 110 |
# File 'lib/anycable/rails/connection.rb', line 108 def socket @socket end |
Instance Method Details
#action_cable_connection ⇒ Object
175 176 177 |
# File 'lib/anycable/rails/connection.rb', line 175 def action_cable_connection conn end |
#build_rack_request(env) ⇒ Object
168 169 170 171 172 173 |
# File 'lib/anycable/rails/connection.rb', line 168 def build_rack_request(env) environment = ::Rails.application.env_config.merge(env) if defined?(::Rails.application) && ::Rails.application AnyCable::Rails::Rack.app.call(environment) if environment ActionDispatch::Request.new(environment || env) end |
#close ⇒ Object
179 180 181 182 183 |
# File 'lib/anycable/rails/next/connection.rb', line 179 def close(...) return if socket.closed? logger.info if access_logs? socket.close(...) end |
#handle_channel_command(identifier, command, data) ⇒ Object
159 160 161 162 163 164 165 166 |
# File 'lib/anycable/rails/connection.rb', line 159 def handle_channel_command(identifier, command, data) conn.run_callbacks :command do conn.subscriptions.execute_rpc_command({"command" => command, "identifier" => identifier, "data" => data}) end rescue Exception => e # rubocop:disable Lint/RescueException rescue_with_handler(e) || raise false end |
#handle_close ⇒ Object
151 152 153 154 155 156 157 |
# File 'lib/anycable/rails/connection.rb', line 151 def handle_close logger.info if access_logs? conn.subscriptions.unsubscribe_from_all conn.disconnect if conn.respond_to?(:disconnect) true end |
#handle_open ⇒ Object
AnyCable RPC interface [BEGIN] ==
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/anycable/rails/next/connection.rb', line 136 def handle_open logger.info if access_logs? verify_origin! || return conn.connect if conn.respond_to?(:connect) socket.cstate.write(LOG_TAGS_IDENTIFIER, logger..to_json) unless logger..empty? conn. rescue ::ActionCable::Connection::Authorization:: reject_request( ActionCable::INTERNAL[:disconnect_reasons]&.[](:unauthorized) || "unauthorized" ) end |
#perform_work(receiver, method_name, *args) ⇒ Object
185 186 187 |
# File 'lib/anycable/rails/next/connection.rb', line 185 def perform_work(receiver, method_name, *args) raise ArgumentError, "Performing work is not supported within AnyCable" end |
#request ⇒ Object
227 228 229 |
# File 'lib/anycable/rails/connection.rb', line 227 def request conn.public_request end |
#transmit(data) ⇒ Object
175 176 177 |
# File 'lib/anycable/rails/next/connection.rb', line 175 def transmit(data) socket.transmit ActiveSupport::JSON.encode(data) end |