Class: ActionCable::Connection::Base
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
|
|
|
Instance Chain:
|
|
| Inherits: | Object |
| Defined in: | actioncable/lib/action_cable/connection/base.rb |
Overview
For every WebSocket connection the Action Cable server accepts, a ::ActionCable::Connection
object will be instantiated. This instance becomes the parent of all of the
channel subscriptions that are created from there on. Incoming messages are
then routed to these channel subscriptions based on an identifier sent by the
Action Cable consumer. The Connection itself does not deal with any specific
application logic beyond authentication and authorization.
Here's a basic example:
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
logger. current_user.name
end
def disconnect
# Any cleanup work needed when the cable connection is cut.
end
private
def find_verified_user
User.find_by_identity(.encrypted[:identity_id]) ||
end
end
end
First, we declare that this connection can be identified by its current_user. This allows us to later be able to find all connections established for that current_user (and potentially disconnect them). You can declare as many identification indexes as you like. Declaring an identification means that an attr_accessor is automatically set for that key.
Second, we rely on the fact that the WebSocket connection is established with the cookies from the domain being sent along. This makes it easy to use signed cookies that were set when logging in via a web interface to authorize the WebSocket connection.
Finally, we add a tag to the connection-specific logger with the name of the current user to easily distinguish their messages in the log.
Constant Summary
::ActiveSupport::Callbacks - Included
Identification - Attributes & Methods
::ActiveSupport::Rescuable - Attributes & Methods
Class Method Summary
- .new(server, socket) ⇒ Base constructor
::ActiveSupport::DescendantsTracker - self
Instance Attribute Summary
- #broadcast readonly
- #config readonly
- #env readonly
- #executor readonly
- #logger readonly
- #perform_work readonly
- #protocol readonly
- #pubsub readonly
- #request readonly
- #subscriptions readonly
- #server readonly private
- #socket readonly private
Callbacks - Included
Instance Method Summary
- #beat
-
#close(reason: nil, reconnect: true)
Close the connection.
-
#connect
This method is called every time an Action Cable client establishes an underlying connection.
-
#disconnect
This method is called every time an Action Cable client disconnects.
- #handle_channel_command(payload) (also: #handle_incoming)
- #handle_close
-
#handle_incoming(payload)
Alias for #handle_channel_command.
- #handle_open
-
#statistics
Return a basic hash of statistics for the connection keyed with
identifier,started_at, #subscriptions, andrequest_id. -
#cookies
private
The cookies of the request that initiated the WebSocket connection.
- #instance_variables_to_inspect private
- #send_welcome_message private
- #transmit(data) Internal use only
::ActiveSupport::Rescuable - Included
| #rescue_with_handler | Delegates to the class method, but uses the instance as the subject for rescue_from handlers (method calls, |
| #handler_for_rescue | Internal handler lookup. |
::ActiveSupport::Callbacks - Included
| #run_callbacks | Runs the callbacks for the given event. |
| #halted_callback_hook | A hook invoked every time a before callback is halted. |
Authorization - Included
| #reject_unauthorized_connection | Closes the WebSocket connection if it is open and returns an "unauthorized" reason. |
InternalChannel - Included
| #internal_channel, #process_internal_message, #subscribe_to_internal_channel, #unsubscribe_from_internal_channel |
Identification - Included
| #connection_identifier | Return a single connection identifier that combines the value of all the registered identifiers into a single gid. |
| #connection_gid | |
Constructor Details
.new(server, socket) ⇒ Base
Class Attribute Details
.identifiers (rw)
[ GitHub ]# File 'actioncable/lib/action_cable/connection/identification.rb', line 11
class_attribute :identifiers, default: Set.new
.identifiers? ⇒ Boolean (rw)
[ GitHub ]
# File 'actioncable/lib/action_cable/connection/identification.rb', line 11
class_attribute :identifiers, default: Set.new
.rescue_handlers (rw)
[ GitHub ]# File 'activesupport/lib/active_support/rescuable.rb', line 17
class_attribute :rescue_handlers, default: [].freeze
.rescue_handlers? ⇒ Boolean (rw)
[ GitHub ]
# File 'activesupport/lib/active_support/rescuable.rb', line 17
class_attribute :rescue_handlers, default: [].freeze
Instance Attribute Details
#broadcast (readonly)
[ GitHub ]#config (readonly)
[ GitHub ]#env (readonly)
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 68
delegate :env, :request, :protocol, :perform_work, to: :socket, allow_nil: true
#executor (readonly)
[ GitHub ]#identifiers (rw)
[ GitHub ]# File 'actioncable/lib/action_cable/connection/identification.rb', line 11
class_attribute :identifiers, default: Set.new
#identifiers? ⇒ Boolean (rw)
[ GitHub ]
# File 'actioncable/lib/action_cable/connection/identification.rb', line 11
class_attribute :identifiers, default: Set.new
#logger (readonly)
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 65
attr_reader :subscriptions, :logger
#perform_work (readonly)
[ GitHub ]#protocol (readonly)
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 68
delegate :env, :request, :protocol, :perform_work, to: :socket, allow_nil: true
#pubsub (readonly)
[ GitHub ]#request (readonly)
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 68
delegate :env, :request, :protocol, :perform_work, to: :socket, allow_nil: true
#rescue_handlers (rw)
[ GitHub ]# File 'activesupport/lib/active_support/rescuable.rb', line 17
class_attribute :rescue_handlers, default: [].freeze
#rescue_handlers? ⇒ Boolean (rw)
[ GitHub ]
# File 'activesupport/lib/active_support/rescuable.rb', line 17
class_attribute :rescue_handlers, default: [].freeze
#server (readonly, private)
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 151
attr_reader :server, :socket
#socket (readonly, private)
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 151
attr_reader :server, :socket
#subscriptions (readonly)
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 65
attr_reader :subscriptions, :logger
Instance Method Details
#beat
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 144
def beat transmit type: ActionCable::INTERNAL[:][:ping], message: Time.now.to_i end
#close(reason: nil, reconnect: true)
Close the connection.
# File 'actioncable/lib/action_cable/connection/base.rb', line 123
def close(reason: nil, reconnect: true) transmit( type: ActionCable::INTERNAL[:][:disconnect], reason: reason, reconnect: reconnect ) rescue nil socket.close end
#connect
This method is called every time an Action Cable client establishes an underlying connection. Override it in your class to define authentication logic and populate connection identifiers.
# File 'actioncable/lib/action_cable/connection/base.rb', line 85
def connect end
#cookies (private)
The cookies of the request that initiated the WebSocket connection. Useful for performing authorization checks.
# File 'actioncable/lib/action_cable/connection/base.rb', line 158
def # :doc: request. end
#disconnect
This method is called every time an Action Cable client disconnects. Override it in your class to cleanup the relevant application state (e.g., presence, online counts, etc.)
# File 'actioncable/lib/action_cable/connection/base.rb', line 90
def disconnect end
#handle_channel_command(payload) Also known as: #handle_incoming
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 108
def handle_channel_command(payload) run_callbacks :command do subscriptions.execute_command payload end rescue Exception => e rescue_with_handler(e) || raise end
#handle_close
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 101
def handle_close subscriptions.unsubscribe_from_all unsubscribe_from_internal_channel disconnect end
#handle_incoming(payload)
Alias for #handle_channel_command.
# File 'actioncable/lib/action_cable/connection/base.rb', line 116
alias_method :handle_incoming, :handle_channel_command
#handle_open
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 93
def handle_open connect subscribe_to_internal_channel rescue ActionCable::Connection::Authorization::UnauthorizedError close(reason: ActionCable::INTERNAL[:disconnect_reasons][:], reconnect: false) end
#instance_variables_to_inspect (private)
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 153
def instance_variables_to_inspect [].freeze end
#send_welcome_message (private)
[ GitHub ]# File 'actioncable/lib/action_cable/connection/base.rb', line 162
def # Send welcome message to the internal connection monitor channel. This ensures # the connection monitor state is reset after a successful websocket connection. transmit type: ActionCable::INTERNAL[:][:welcome] end
#statistics
Return a basic hash of statistics for the connection keyed with identifier,
started_at, #subscriptions, and request_id. This can be returned by a
health check against the connection.
# File 'actioncable/lib/action_cable/connection/base.rb', line 135
def statistics { identifier: connection_identifier, started_at: @started_at, subscriptions: subscriptions.identifiers, request_id: env["action_dispatch.request_id"] } end
#transmit(data)
# File 'actioncable/lib/action_cable/connection/base.rb', line 118
def transmit(data) # :nodoc: socket.transmit(data) end