跳到內容 跳到搜尋

Action Cable Connection Base

對於 Action Cable 伺服器接受的每個 WebSocket 連線,將會執行個體化 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 變得容易,該簽署的 Cookie 是在使用者透過網路介面登入時設定,用於授權 WebSocket 連線。

最後,我們使用目前使用者的名稱,將標籤新增到特定於連線的記錄器,以便在記錄中輕易區分其訊息。

很簡單吧?

方法
B
C
H
N
R
S
包含的模組

屬性

[R] env
[R] logger
[R] protocol
[R] server
[R] subscriptions
[R] worker_pool

類別公開方法

new(server, env, coder: ActiveSupport::JSON)

# 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

個體公開方法

beat()

# 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

close(reason: nil, reconnect: true)

關閉 WebSocket 連線。

# 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

handle_channel_command(payload)

# 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

send_async(method, *arguments)

透過作業執行緒池中非同步呼叫連線上的某個方法。

# File actioncable/lib/action_cable/connection/base.rb, line 131
def send_async(method, *arguments)
  worker_pool.async_invoke(self, method, *arguments)
end

statistics()

傳回一組基本連線統計資料,並以 identifierstarted_atsubscriptionsrequest_id 作為鍵值。健康檢查連線時會傳回這些資訊。

# 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

實例私人方法

cookies()

初始 WebSocket 連線時的要求 Cookie。對於執行授權檢查很有用。

# File actioncable/lib/action_cable/connection/base.rb, line 187
def cookies # :doc:
  request.cookie_jar
end

request()

於此提供初始 WebSocket 連線時的要求。這可以讓存取環境、Cookie 等。

# 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