class ActionCable::Connection::Base
Action Cable Base
Для каждого WebSocket-соединения, принимаемого сервером Action Cable, создаётся объект Connection. Этот экземпляр становится родителем всех подписок на каналы, созданных после этого. Затем входящие сообщения направляются этим подпискам на каналы на основании идентификатора, отправленного клиентом Action Cable. Сам объект Connection не занимается никакой конкретной логикой приложения, кроме аутентификации и авторизации.
Вот простой пример:
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
logger.add_tags 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(cookies.encrypted[:identity_id]) ||
reject_unauthorized_connection
end
end
end
Сначала мы объявляем, что это соединение можно идентифицировать по его current_user. Это позволяет нам впоследствии находить все соединения, установленные для этого current_user (и при необходимости отключать их). Можно объявить любое количество индексов идентификации. При объявлении идентификатора для этого ключа автоматически устанавливается attr_accessor.
Во-вторых, мы исходим из того, что WebSocket-соединение устанавливается с передачей файлов cookie домена. Это позволяет легко использовать подписанные файлы cookie, заданные при входе через веб-интерфейс, для авторизации WebSocket-соединения.
Наконец, мы добавляем в журнал соединения тег с именем текущего пользователя, чтобы можно было легко различать его сообщения в журнале.
Довольно просто, не так ли?
Атрибуты
Публичные методы класса
# File actioncable/lib/action_cable/connection/base.rb, line 67 def initialize(server, env, coder: ActiveSupport::JSON) @server, @env, @coder = server, env, coder @worker_pool = server.worker_pool @logger = new_tagged_logger @websocket = ActionCable::Connection::WebSocket.new(env, self, event_loop) @subscriptions = ActionCable::Connection::Subscriptions.new(self) @message_buffer = ActionCable::Connection::MessageBuffer.new(self) @_internal_subscriptions = nil @started_at = Time.now end
Публичные методы экземпляра
# File actioncable/lib/action_cable/connection/base.rb, line 147 def beat transmit type: ActionCable::INTERNAL[:message_types][:ping], message: Time.now.to_i end
# File actioncable/lib/action_cable/connection/base.rb, line 120
def close(reason: nil, reconnect: true)
transmit(
type: ActionCable::INTERNAL[:message_types][:disconnect],
reason: reason,
reconnect: reconnect
)
websocket.close
end Закрывает WebSocket-соединение.
# File actioncable/lib/action_cable/connection/base.rb, line 109
def handle_channel_command(payload)
run_callbacks :command do
subscriptions.execute_command payload
end
end # File actioncable/lib/action_cable/connection/base.rb, line 131 def send_async(method, *arguments) worker_pool.async_invoke(self, method, *arguments) end
Асинхронно вызывает метод соединения через пул потоков-обработчиков.
# File actioncable/lib/action_cable/connection/base.rb, line 138
def statistics
{
identifier: connection_identifier,
started_at: @started_at,
subscriptions: subscriptions.identifiers,
request_id: @env["action_dispatch.request_id"]
}
end Возвращает базовый хеш статистики соединения с ключами identifier, started_at, subscriptions и request_id. Его можно возвращать в ответ на проверку работоспособности соединения.
Приватные методы экземпляра
# File actioncable/lib/action_cable/connection/base.rb, line 187 def cookies # :doc: request.cookie_jar end
Файлы cookie запроса, инициировавшего WebSocket-соединение. Полезны для выполнения проверок авторизации.
# File actioncable/lib/action_cable/connection/base.rb, line 178
def request # :doc:
@request ||= begin
environment = Rails.application.env_config.merge(env) if defined?(Rails.application) && Rails.application
ActionDispatch::Request.new(environment || env)
end
end Здесь доступен запрос, инициировавший WebSocket-соединение. Это даёт доступ к окружению, файлам cookie и т. д.
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.