класс ActionCable::Connection::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
Во-первых, мы объявляем, что это соединение можно идентифицировать по текущему пользователю. Это позволяет нам позже найти все соединения, установленные для этого текущего пользователя (и потенциально разорвать их). Вы можете объявлять столько индексов идентификации, сколько нужно. Объявление идентификации означает, что для этого ключа автоматически устанавливается attr_accessor.
Во-вторых, мы полагаемся на то, что WebSocket-соединение устанавливается с кукис с домена, отправляемыми вместе. Это облегчает использование подписанных кукис, установленных при входе в систему через веб-интерфейс, для авторизации WebSocket-соединения.
Наконец, мы добавляем метку в подключенный логгер с именем текущего пользователя, чтобы легко различать их сообщения в логе.
Довольно просто, да?
Атрибуты
TODO Изменить на private после отключения поддержки Ruby 2.2. Решение для предупреждения Ruby 2.2 “private attribute?”.
Публичные методы класса
# File actioncable/lib/action_cable/connection/base.rb, line 53 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 118 def beat transmit type: ActionCable::INTERNAL[:message_types][:ping], message: Time.now.to_i end
# File actioncable/lib/action_cable/connection/base.rb, line 98 def close websocket.close end
Закрыть WebSocket-соединение.
# File actioncable/lib/action_cable/connection/base.rb, line 103 def send_async(method, *arguments) worker_pool.async_invoke(self, method, *arguments) end
Вызвать метод соединения асинхронно через пул потоковых рабочих процессов.
# File actioncable/lib/action_cable/connection/base.rb, line 109
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 155 def cookies # :doc: request.cookie_jar end
Куки запроса, который инициировал WebSocket-соединение. Полезно для выполнения проверок авторизации.
# File actioncable/lib/action_cable/connection/base.rb, line 147
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-соединение, доступен здесь. Это предоставляет доступ к среде, кукисам и т. д.
© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.