Class: ActionCable::Connection::Base
- Inherits:
-
Object
- Object
- ActionCable::Connection::Base
- Includes:
- Authorization, Callbacks, Identification, InternalChannel, ActiveSupport::Rescuable
- Defined in:
- lib/action_cable/connection/base.rb
Overview
# Action Cable Connection Base
For every WebSocket connection the Action Cable server accepts, a 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.
Instance Attribute Summary collapse
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
-
#subscriptions ⇒ Object
readonly
Returns the value of attribute subscriptions.
Class Method Summary collapse
Instance Method Summary collapse
- #beat ⇒ Object
-
#close(reason: nil, reconnect: true) ⇒ Object
Close the connection.
-
#connect ⇒ Object
This method is called every time an Action Cable client establishes an underlying connection.
-
#disconnect ⇒ Object
This method is called every time an Action Cable client disconnects.
- #handle_channel_command(payload) ⇒ Object (also: #handle_incoming)
- #handle_close ⇒ Object
- #handle_open ⇒ Object
-
#initialize(server, socket) ⇒ Base
constructor
A new instance of Base.
-
#inspect ⇒ Object
:nodoc:.
-
#raw_transmit(data) ⇒ Object
:nodoc:.
-
#statistics ⇒ Object
Return a basic hash of statistics for the connection keyed with
identifier,started_at,subscriptions, andrequest_id. -
#transmit(data) ⇒ Object
:nodoc:.
Methods included from Authorization
#reject_unauthorized_connection
Methods included from Identification
Constructor Details
#initialize(server, socket) ⇒ Base
Returns a new instance of Base.
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/action_cable/connection/base.rb', line 68 def initialize(server, socket) @server = server @socket = socket @logger = socket.logger @subscriptions = Subscriptions.new(self) @_internal_subscriptions = nil @started_at = Time.now end |
Instance Attribute Details
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
62 63 64 |
# File 'lib/action_cable/connection/base.rb', line 62 def logger @logger end |
#subscriptions ⇒ Object (readonly)
Returns the value of attribute subscriptions.
62 63 64 |
# File 'lib/action_cable/connection/base.rb', line 62 def subscriptions @subscriptions end |
Class Method Details
.__restore_visibility__ ⇒ Object
173 174 175 176 177 |
# File 'lib/action_cable/connection/base.rb', line 173 def __restore_visibility__ i[handle_open handle_close handle_channel_command transmit close].each do |method| instance_method(method).owner.send(:public, method) end end |
Instance Method Details
#beat ⇒ Object
146 147 148 |
# File 'lib/action_cable/connection/base.rb', line 146 def beat transmit type: ActionCable::INTERNAL[:message_types][:ping], message: Time.now.to_i end |
#close(reason: nil, reconnect: true) ⇒ Object
Close the connection.
125 126 127 128 129 130 131 132 |
# File 'lib/action_cable/connection/base.rb', line 125 def close(reason: nil, reconnect: true) transmit( type: ActionCable::INTERNAL[:message_types][:disconnect], reason: reason, reconnect: reconnect ) socket.close end |
#connect ⇒ Object
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.
83 84 |
# File 'lib/action_cable/connection/base.rb', line 83 def connect end |
#disconnect ⇒ Object
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.)
88 89 |
# File 'lib/action_cable/connection/base.rb', line 88 def disconnect end |
#handle_channel_command(payload) ⇒ Object Also known as: handle_incoming
106 107 108 109 110 111 112 |
# File 'lib/action_cable/connection/base.rb', line 106 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 ⇒ Object
99 100 101 102 103 104 |
# File 'lib/action_cable/connection/base.rb', line 99 def handle_close subscriptions.unsubscribe_from_all unsubscribe_from_internal_channel disconnect end |
#handle_open ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/action_cable/connection/base.rb', line 91 def handle_open connect subscribe_to_internal_channel rescue ActionCable::Connection::Authorization:: close(reason: ActionCable::INTERNAL[:disconnect_reasons][:unauthorized], reconnect: false) end |
#inspect ⇒ Object
:nodoc:
150 151 152 |
# File 'lib/action_cable/connection/base.rb', line 150 def inspect # :nodoc: "#<#{self.class.name}:#{'%#016x' % (object_id << 1)}>" end |
#raw_transmit(data) ⇒ Object
:nodoc:
120 121 122 |
# File 'lib/action_cable/connection/base.rb', line 120 def raw_transmit(data) # :nodoc: socket.raw_transmit(data) end |
#statistics ⇒ Object
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.
137 138 139 140 141 142 143 144 |
# File 'lib/action_cable/connection/base.rb', line 137 def statistics { identifier: connection_identifier, started_at: @started_at, subscriptions: subscriptions.identifiers, request_id: env["action_dispatch.request_id"] } end |
#transmit(data) ⇒ Object
:nodoc:
116 117 118 |
# File 'lib/action_cable/connection/base.rb', line 116 def transmit(data) # :nodoc: socket.transmit(data) end |