v7.1.3.2
更多資訊請至 rubyonrails.org: 更多 Ruby on Rails

Action Cable 概觀

在本指南中,您將了解 Action Cable 的運作方式,以及如何使用 WebSockets 將即時功能納入您的 Rails 應用程式。

閱讀本指南後,您將知道

1 什麼是 Action Cable?

Action Cable 將 WebSocket 與 Rails 應用程式的其他部分無縫整合。它允許使用 Ruby 編寫即時功能,其樣式和形式與 Rails 應用程式的其他部分相同,同時仍具有效能且可擴充。它是一個全端堆疊服務,提供用戶端 JavaScript 架構和伺服器端 Ruby 架構。您可以存取使用 Active Record 或您選擇的 ORM 編寫的完整網域模型。

2 術語

Action Cable 使用 WebSocket,而不是 HTTP 請求回應協定。Action Cable 和 WebSocket 都引入了一些較不熟悉的術語

2.1 連線

連線形成用戶端伺服器關係的基礎。單一 Action Cable 伺服器可以處理多個連線執行個體。它在每個 WebSocket 連線中有一個連線執行個體。如果單一使用者使用多個瀏覽器分頁或裝置,他們可能會開啟多個 WebSocket 連線到您的應用程式。

2.2 使用者

WebSocket 連線的用戶端稱為使用者。在 Action Cable 中,使用者是由用戶端 JavaScript 架構建立的。

2.3 頻道

每個使用者都可以進一步訂閱多個頻道。每個頻道封裝一個邏輯工作單元,類似於控制器在典型 MVC 設定中所做的工作。例如,您可以有一個 ChatChannel 和一個 AppearancesChannel,使用者可以訂閱這些頻道中的任何一個或兩個頻道。至少,使用者應該訂閱一個頻道。

2.4 訂閱者

當使用者訂閱頻道時,他們會作為訂閱者。訂閱者和頻道之間的連線,驚喜的是,稱為訂閱。使用者可以多次作為訂閱者訂閱特定頻道。例如,使用者可以同時訂閱多個聊天室。(請記住,實際使用者可能有多個使用者,每個使用者對您的連線開啟一個分頁/裝置)。

2.5 發佈/訂閱

Pub/Sub 或發布訂閱是指一種訊息佇列範例,其中資訊的發送者(發布者)將資料傳送給一組抽象的接收者(訂閱者),而不會指定個別接收者。Action Cable 使用此方法在伺服器和多個用戶端之間進行通訊。

2.6 廣播

廣播是一種 pub/sub 連結,其中廣播者傳輸的任何內容都會直接傳送給訂閱該命名廣播的頻道訂閱者。每個頻道可以串流零個或多個廣播。

3 伺服器端元件

3.1 連線

對於伺服器接受的每個 WebSocket,會實例化一個連線物件。此物件會成為從此處建立的所有頻道訂閱的父物件。連線本身不會處理任何特定應用程式邏輯,只會處理驗證和授權。WebSocket 連線的用戶端稱為連線使用者。個別使用者會為他們開啟的每個瀏覽器分頁、視窗或裝置建立一組使用者連線。

連線是 ApplicationCable::Connection 的實例,它會延伸 ActionCable::Connection::Base。在 ApplicationCable::Connection 中,您會授權傳入連線,並在可以識別使用者的情況下繼續建立連線。

3.1.1 連線設定

# app/channels/application_cable/connection.rb
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
    end

    private
      def find_verified_user
        if verified_user = User.find_by(id: cookies.encrypted[:user_id])
          verified_user
        else
          reject_unauthorized_connection
        end
      end
  end
end

在這裡,identified_by 指定一個連線識別碼,可用於稍後尋找特定連線。請注意,任何標記為識別碼的內容都會自動在從連線建立的任何頻道實例上建立一個具有相同名稱的委派。

此範例依賴於您已經在應用程式的其他地方處理使用者的驗證,而且成功的驗證會設定一個包含使用者 ID 的加密 Cookie。

當嘗試建立新連線時,Cookie 會自動傳送到連線實例,而你使用它來設定 current_user。透過此相同目前使用者來識別連線,你也可以確保稍後可以擷取特定使用者開啟的所有連線(如果使用者已刪除或未授權,則可能會將所有連線中斷)。

如果你的驗證方法包含使用階段,則你對階段使用 Cookie 儲存,你的階段 Cookie 會命名為 _session,而使用者 ID 金鑰為 user_id,你可以使用此方法

verified_user = User.find_by(id: cookies.encrypted['_session']['user_id'])

3.1.2 例外處理

預設情況下,未處理的例外會被捕捉並記錄到 Rails 的記錄器。如果你想要全面攔截這些例外並將它們報告給外部錯誤追蹤服務,例如,你可以使用 rescue_from

# app/channels/application_cable/connection.rb
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    rescue_from StandardError, with: :report_error

    private
      def report_error(e)
        SomeExternalBugtrackingService.notify(e)
      end
  end
end

3.1.3 連線回呼

ActionCable::Connection::Callbacks 提供在傳送命令給客戶端時呼叫的回呼掛鉤,例如在訂閱、取消訂閱或執行動作時

3.2 頻道

頻道 封裝一個邏輯工作單元,類似於控制器在典型 MVC 設定中所做的工作。預設情況下,Rails 會建立一個父類 ApplicationCable::Channel(延伸 ActionCable::Channel::Base)來封裝頻道之間的共用邏輯。

3.2.1 父頻道設定

# app/channels/application_cable/channel.rb
module ApplicationCable
  class Channel < ActionCable::Channel::Base
  end
end

然後,你會建立自己的頻道類別。例如,你可以有一個 ChatChannel 和一個 AppearanceChannel

# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
end
# app/channels/appearance_channel.rb
class AppearanceChannel < ApplicationCable::Channel
end

然後,使用者可以訂閱這些頻道中的任何一個或兩個頻道。

3.2.2 訂閱

使用者訂閱頻道,擔任訂閱者。他們的連線稱為訂閱。然後,根據頻道使用者傳送的識別碼,將產生的訊息路由到這些頻道訂閱。

# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
  # Called when the consumer has successfully
  # become a subscriber to this channel.
  def subscribed
  end
end

3.2.3 例外處理

ApplicationCable::Connection 一樣,您也可以在特定頻道上使用 rescue_from 來處理引發的例外

# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
  rescue_from 'MyError', with: :deliver_error_message

  private
    def deliver_error_message(e)
      # broadcast_to(...)
    end
end

3.2.4 頻道回呼

ActionCable::Channel::Callbacks 提供在頻道生命週期中呼叫的回呼掛鉤

4 客户端組件

4.1 連線

消費者需要在其端建立連線實例。這可以使用以下 JavaScript 建立,Rails 預設會產生此 JavaScript

4.1.1 連線消費者

// app/javascript/channels/consumer.js
// Action Cable provides the framework to deal with WebSockets in Rails.
// You can generate new channels where WebSocket features live using the `bin/rails generate channel` command.

import { createConsumer } from "@rails/actioncable"

export default createConsumer()

這將準備一個消費者,預設會在您的伺服器上連線到 /cable。在您至少指定一個您有興趣的訂閱之前,連線不會建立。

消費者可以選擇接受一個指定要連線的 URL 的引數。這可以是字串或會在 WebSocket 開啟時呼叫的傳回字串的函式。

// Specify a different URL to connect to
createConsumer('wss://example.com/cable')
// Or when using websockets over HTTP
createConsumer('https://ws.example.com/cable')

// Use a function to dynamically generate the URL
createConsumer(getWebSocketURL)

function getWebSocketURL() {
  const token = localStorage.get('auth-token')
  return `wss://example.com/cable?token=${token}`
}

4.1.2 訂閱者

消費者透過建立對特定頻道的訂閱成為訂閱者

// app/javascript/channels/chat_channel.js
import consumer from "./consumer"

consumer.subscriptions.create({ channel: "ChatChannel", room: "Best Room" })

// app/javascript/channels/appearance_channel.js
import consumer from "./consumer"

consumer.subscriptions.create({ channel: "AppearanceChannel" })

雖然這會建立訂閱,但回應接收資料所需的功能將在稍後說明。

消費者可以多次擔任特定頻道的訂閱者。例如,消費者可以同時訂閱多個聊天室

// app/javascript/channels/chat_channel.js
import consumer from "./consumer"

consumer.subscriptions.create({ channel: "ChatChannel", room: "1st Room" })
consumer.subscriptions.create({ channel: "ChatChannel", room: "2nd Room" })

5 伺服器端互動

5.1 串流

串流提供頻道將發布內容(廣播)路由到其訂閱者的機制。例如,以下程式碼使用 stream_from:room 參數值為 "Best Room" 時訂閱名為 chat_Best Room 的廣播

# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
  def subscribed
    stream_from "chat_#{params[:room]}"
  end
end

然後,您可以在 Rails 應用程式的其他地方呼叫 broadcast 來對此類房間進行廣播

ActionCable.server.broadcast("chat_Best Room", { body: "This Room is Best Room." })

如果您有一個與模型相關的串流,則可以從頻道和模型產生廣播名稱。例如,以下程式碼使用 stream_for 訂閱 posts:Z2lkOi8vVGVzdEFwcC9Qb3N0LzE 等廣播,其中 Z2lkOi8vVGVzdEFwcC9Qb3N0LzE 是 Post 模型的 GlobalID。

class PostsChannel < ApplicationCable::Channel
  def subscribed
    post = Post.find(params[:id])
    stream_for post
  end
end

然後,您可以呼叫 broadcast_to 來對此頻道進行廣播

PostsChannel.broadcast_to(@post, @comment)

5.2 廣播

廣播是一個發布/訂閱連結,其中發布者傳輸的任何內容都會直接路由到串流該命名廣播的頻道訂閱者。每個頻道可以串流零個或多個廣播。

廣播純粹是線上佇列且依時間而定。如果消費者沒有串流(訂閱給定頻道),他們在稍後連線時將不會收到廣播。

5.3 訂閱

當消費者訂閱頻道時,他們會扮演訂閱者的角色。此連線稱為訂閱。然後,根據有線電視消費者傳送的識別碼,將傳入訊息路由到這些頻道訂閱。

// app/javascript/channels/chat_channel.js
import consumer from "./consumer"

consumer.subscriptions.create({ channel: "ChatChannel", room: "Best Room" }, {
  received(data) {
    this.appendLine(data)
  },

  appendLine(data) {
    const html = this.createLine(data)
    const element = document.querySelector("[data-chat-room='Best Room']")
    element.insertAdjacentHTML("beforeend", html)
  },

  createLine(data) {
    return `
      <article class="chat-line">
        <span class="speaker">${data["sent_by"]}</span>
        <span class="body">${data["body"]}</span>
      </article>
    `
  }
})

5.4 將參數傳遞至頻道

建立訂閱時,您可以從用戶端傳遞參數至伺服器端。例如

# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
  def subscribed
    stream_from "chat_#{params[:room]}"
  end
end

傳遞至 subscriptions.create 第一個引數的物件會成為有線頻道中的 params hash。需要 channel 關鍵字

// app/javascript/channels/chat_channel.js
import consumer from "./consumer"

consumer.subscriptions.create({ channel: "ChatChannel", room: "Best Room" }, {
  received(data) {
    this.appendLine(data)
  },

  appendLine(data) {
    const html = this.createLine(data)
    const element = document.querySelector("[data-chat-room='Best Room']")
    element.insertAdjacentHTML("beforeend", html)
  },

  createLine(data) {
    return `
      <article class="chat-line">
        <span class="speaker">${data["sent_by"]}</span>
        <span class="body">${data["body"]}</span>
      </article>
    `
  }
})
# Somewhere in your app this is called, perhaps
# from a NewCommentJob.
ActionCable.server.broadcast(
  "chat_#{room}",
  {
    sent_by: 'Paul',
    body: 'This is a cool chat app.'
  }
)

5.5 重新廣播訊息

常見的用例是將一個用戶端傳送的訊息重新廣播給任何其他已連線的用戶端。

# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
  def subscribed
    stream_from "chat_#{params[:room]}"
  end

  def receive(data)
    ActionCable.server.broadcast("chat_#{params[:room]}", data)
  end
end
// app/javascript/channels/chat_channel.js
import consumer from "./consumer"

const chatChannel = consumer.subscriptions.create({ channel: "ChatChannel", room: "Best Room" }, {
  received(data) {
    // data => { sent_by: "Paul", body: "This is a cool chat app." }
  }
})

chatChannel.send({ sent_by: "Paul", body: "This is a cool chat app." })

所有已連線的用戶端都會收到重新廣播,包括傳送訊息的用戶端。請注意,訂閱頻道時,params 與當時相同。

6 完整堆疊範例

下列設定步驟適用於兩個範例

  1. 設定連線.
  2. 設定父頻道.
  3. 連線消費者.

6.1 範例 1:使用者外觀

以下是一個頻道的簡單範例,用於追蹤使用者是否在線上,以及他們在哪個頁面上。(這對於建立臨場感功能很有用,例如在使用者在線上時,在使用者名稱旁邊顯示綠點)。

建立伺服器端外觀頻道

# app/channels/appearance_channel.rb
class AppearanceChannel < ApplicationCable::Channel
  def subscribed
    current_user.appear
  end

  def unsubscribed
    current_user.disappear
  end

  def appear(data)
    current_user.appear(on: data['appearing_on'])
  end

  def away
    current_user.away
  end
end

當訂閱啟動時,會觸發 subscribed 回呼,我們利用這個機會說「目前的使用者確實出現了」。此出現/消失 API 可以由 Redis、資料庫或其他任何東西作為後盾。

建立用戶端外觀頻道訂閱

// app/javascript/channels/appearance_channel.js
import consumer from "./consumer"

consumer.subscriptions.create("AppearanceChannel", {
  // Called once when the subscription is created.
  initialized() {
    this.update = this.update.bind(this)
  },

  // Called when the subscription is ready for use on the server.
  connected() {
    this.install()
    this.update()
  },

  // Called when the WebSocket connection is closed.
  disconnected() {
    this.uninstall()
  },

  // Called when the subscription is rejected by the server.
  rejected() {
    this.uninstall()
  },

  update() {
    this.documentIsActive ? this.appear() : this.away()
  },

  appear() {
    // Calls `AppearanceChannel#appear(data)` on the server.
    this.perform("appear", { appearing_on: this.appearingOn })
  },

  away() {
    // Calls `AppearanceChannel#away` on the server.
    this.perform("away")
  },

  install() {
    window.addEventListener("focus", this.update)
    window.addEventListener("blur", this.update)
    document.addEventListener("turbo:load", this.update)
    document.addEventListener("visibilitychange", this.update)
  },

  uninstall() {
    window.removeEventListener("focus", this.update)
    window.removeEventListener("blur", this.update)
    document.removeEventListener("turbo:load", this.update)
    document.removeEventListener("visibilitychange", this.update)
  },

  get documentIsActive() {
    return document.visibilityState === "visible" && document.hasFocus()
  },

  get appearingOn() {
    const element = document.querySelector("[data-appearing-on]")
    return element ? element.getAttribute("data-appearing-on") : null
  }
})

6.1.1 用戶端-伺服器互動

  1. 用戶端透過 createConsumer() 連線至 伺服器。(consumer.js)。伺服器透過 current_user 識別此連線。

  2. 用戶端透過 consumer.subscriptions.create({ channel: "AppearanceChannel" }) 訂閱外觀頻道。(appearance_channel.js)

  3. 伺服器辨識已為外觀頻道啟動新的訂閱,並執行其 subscribed 回呼,呼叫 current_user 上的 appear 方法。(appearance_channel.rb)

  4. 用戶端辨識已建立訂閱,並呼叫 connected (appearance_channel.js),進而呼叫 installappearappear 在伺服器上呼叫 AppearanceChannel#appear(data),並提供 { appearing_on: this.appearingOn } 的資料雜湊。這之所以可行,是因為伺服器端頻道實例會自動公開類別上宣告的所有公開方法 (減去回呼),以便這些方法可透過訂閱的 perform 方法作為遠端程序呼叫來存取。

  5. 伺服器收到對 current_user 識別的連線中外觀頻道上 appear 動作的要求 (appearance_channel.rb)。伺服器從資料雜湊中擷取具有 :appearing_on 鍵的資料,並將其設定為傳遞給 current_user.appear:on 鍵的值。

6.2 範例 2:接收新的網路通知

外觀範例都是關於將伺服器功能公開給透過 WebSocket 連線的用戶端端呼叫。但 WebSocket 的優點在於它是雙向的。因此,現在讓我們示範伺服器在用戶端上呼叫動作的範例。

這是一個網路通知頻道,讓您在廣播到相關串流時觸發用戶端端的網路通知

建立伺服器端的網路通知頻道

# app/channels/web_notifications_channel.rb
class WebNotificationsChannel < ApplicationCable::Channel
  def subscribed
    stream_for current_user
  end
end

建立用戶端端的網路通知頻道訂閱

// app/javascript/channels/web_notifications_channel.js
// Client-side which assumes you've already requested
// the right to send web notifications.
import consumer from "./consumer"

consumer.subscriptions.create("WebNotificationsChannel", {
  received(data) {
    new Notification(data["title"], { body: data["body"] })
  }
})

從應用程式的其他地方廣播內容至網路通知頻道實例

# Somewhere in your app this is called, perhaps from a NewCommentJob
WebNotificationsChannel.broadcast_to(
  current_user,
  title: 'New things!',
  body: 'All the news fit to print'
)

WebNotificationsChannel.broadcast_to 呼叫會將訊息置於目前的訂閱適配器的 pubsub佇列中,每個使用者的廣播名稱都不同。對於 ID 為 1 的使用者,廣播名稱會是 web_notifications:1

頻道已指示透過呼叫 received 回呼,將所有到達 web_notifications:1 的內容直接串流至用戶端。傳遞為引數的資料是作為伺服器端廣播呼叫的第二個參數傳送的雜湊,經過 JSON 編碼以透過網路傳輸,並解開為作為 received 到達的資料引數。

6.3 更完整的範例

請參閱 rails/actioncable-examples 儲存庫,以取得如何在 Rails 應用程式中設定 Action Cable 並新增頻道的完整範例。

7 設定

Action Cable 有兩個必要的設定:訂閱適配器和允許的請求來源。

7.1 訂閱適配器

預設情況下,Action Cable 會在 config/cable.yml 中尋找設定檔。此檔案必須為每個 Rails 環境指定一個適配器。請參閱 相依性 區段,以取得有關適配器的其他資訊。

development:
  adapter: async

test:
  adapter: test

production:
  adapter: redis
  url: redis://10.10.3.153:6381
  channel_prefix: appname_production

7.1.1 適配器設定

以下是提供給最終使用者的訂閱適配器清單。

7.1.1.1 非同步適配器

非同步適配器用於開發/測試,不應在生產環境中使用。

7.1.1.2 Redis 適配器

Redis 適配器要求使用者提供指向 Redis 伺服器的 URL。此外,可以提供 channel_prefix 以避免在為多個應用程式使用相同的 Redis 伺服器時發生頻道名稱衝突。請參閱 Redis Pub/Sub 文件 以取得更多詳細資料。

Redis 適配器也支援 SSL/TLS 連線。必要的 SSL/TLS 參數可以在設定 YAML 檔案中的 ssl_params 鍵中傳遞。

production:
  adapter: redis
  url: rediss://10.10.3.153:tls_port
  channel_prefix: appname_production
  ssl_params: {
    ca_file: "/path/to/ca.crt"
  }

傳遞給 ssl_params 的選項會直接傳遞給 OpenSSL::SSL::SSLContext#set_params 方法,且可以是 SSL 內容的任何有效屬性。請參閱 OpenSSL::SSL::SSLContext 文件 以取得其他可用的屬性。

如果您在防火牆後方使用自簽證書作為 redis 介面卡,並選擇略過憑證檢查,則 ssl verify_mode 應設定為 OpenSSL::SSL::VERIFY_NONE

除非您完全了解安全性影響,否則不建議在製作環境中使用 VERIFY_NONE。若要為 Redis 介面卡設定這個選項,設定應為 ssl_params: { verify_mode: <%= OpenSSL::SSL::VERIFY_NONE %> }

7.1.1.3 PostgreSQL 介面卡

PostgreSQL 介面卡使用 Active Record 的連線池,因此應用程式的 config/database.yml 資料庫設定會用於其連線。這可能會在未來變更。 #27214

7.2 允許的請求來源

Action Cable 只會接受來自指定來源的請求,這些來源會以陣列傳遞給伺服器設定。來源可以是字串或正規表示式的執行個體,系統會針對其執行比對檢查。

config.action_cable.allowed_request_origins = ['https://rubyonrails.com', %r{http://ruby.*}]

若要停用並允許來自任何來源的請求

config.action_cable.disable_request_forgery_protection = true

預設情況下,Action Cable 允許在開發環境中執行時來自 localhost:3000 的所有請求。

7.3 消費者設定

若要設定 URL,請在 HTML 版面配置 HEAD 中呼叫 action_cable_meta_tag。這會使用 URL 或路徑,通常會透過 config.action_cable.url 在環境設定檔中設定。

7.4 工作人員池設定

工作人員池用於在與伺服器主執行緒隔離的狀態下執行連線回呼和頻道動作。Action Cable 允許應用程式設定工作人員池中同時處理的執行緒數目。

config.action_cable.worker_pool_size = 4

此外,請注意您的伺服器必須提供至少與工作人員相同的資料庫連線數。預設工作人員池大小設定為 4,這表示您必須至少提供 4 個資料庫連線。您可以透過 pool 屬性在 config/database.yml 中變更設定。

7.5 客户端記錄

預設會停用客户端記錄。您可以將 ActionCable.logger.enabled 設為 true 來啟用此功能。

import * as ActionCable from '@rails/actioncable'

ActionCable.logger.enabled = true

7.6 其他設定

另一個常見的設定選項是套用至每個連線記錄器的記錄標籤。以下是一個範例,它會在標記時使用使用者帳戶 ID(如果有的話),否則使用「no-account」

config.action_cable.log_tags = [
  -> request { request.env['user_account_id'] || "no-account" },
  :action_cable,
  -> request { request.uuid }
]

如需所有設定選項的完整清單,請參閱 ActionCable::Server::Configuration 類別。

8 執行獨立的 Cable 伺服器

Action Cable 可以作為 Rails 應用程式的一部分執行,也可以作為獨立的伺服器執行。在開發階段,作為 Rails 應用程式的一部分執行通常沒問題,但在製作階段,您應該將其作為獨立的伺服器執行。

8.1 在應用程式中

Action Cable 可以與您的 Rails 應用程式一起執行。例如,若要在 /websocket 上偵聽 WebSocket 要求,請將路徑指定給 config.action_cable.mount_path

# config/application.rb
class Application < Rails::Application
  config.action_cable.mount_path = '/websocket'
end

如果您在版面配置中呼叫 action_cable_meta_tag,可以使用 ActionCable.createConsumer() 連接到 Cable 伺服器。否則,會將路徑指定為 createConsumer 的第一個引數(例如 ActionCable.createConsumer("/websocket"))。

對於您建立的每個伺服器執行個體,以及伺服器衍生的每個工作執行緒,您還將擁有新的 Action Cable 執行個體,但 Redis 或 PostgreSQL 介接器會讓訊息在連線間同步。

8.2 獨立

纜線伺服器可以與您的正常應用程式伺服器分開。它仍然是 Rack 應用程式,但它是其自己的 Rack 應用程式。建議的基本設定如下

# cable/config.ru
require_relative "../config/environment"
Rails.application.eager_load!

run ActionCable.server

然後啟動伺服器

$ bundle exec puma -p 28080 cable/config.ru

這會在埠 28080 上啟動纜線伺服器。若要告訴 Rails 使用此伺服器,請更新您的設定檔

# config/environments/development.rb
Rails.application.configure do
  config.action_cable.mount_path = nil
  config.action_cable.url = "ws://127.0.0.1:28080" # use wss:// in production
end

最後,請確定您已正確設定消費者

8.3 附註

WebSocket 伺服器無法存取工作階段,但可以存取 Cookie。當您需要處理驗證時,可以使用此功能。您可以在這篇文章中看到使用 Devise 執行此操作的方法:文章

9 相依性

Action Cable 提供訂閱介接器介面來處理其 pubsub 內部。預設會包含非同步、內嵌、PostgreSQL 和 Redis 介接器。新 Rails 應用程式的預設介接器是非同步 (async) 介接器。

Ruby 的部分建立在 websocket-drivernio4rconcurrent-ruby 之上。

10 部署

Action Cable 由 WebSocket 和執行緒的組合提供支援。架構配管和使用者指定的頻道工作都透過利用 Ruby 的原生執行緒支援在內部處理。這表示您可以毫無問題地使用所有現有的 Rails 模型,只要您沒有執行任何執行緒安全性錯誤即可。

Action Cable 伺服器實作 Rack socket hijacking API,因此允許使用多執行緒模式來管理內部連線,而與應用程式伺服器是否為多執行緒無關。

因此,Action Cable 可與 Unicorn、Puma 和 Passenger 等熱門伺服器搭配使用。

11 測試

您可以在 測試指南 中找到如何測試 Action Cable 功能的詳細說明。

回饋

我們鼓勵您協助改善本指南的品質。

如果您發現任何錯字或事實錯誤,請協助我們修正。首先,您可以閱讀我們的 文件貢獻 部分。

您也可能會發現不完整或過時的內容。請務必為 main 新增任何遺漏的文件。請先查看 Edge Guides,以驗證問題是否已在 main 分支中修復。查看 Ruby on Rails 指南指南,以了解風格和慣例。

如果您發現需要修復的事項,但無法自行修補,請 開啟問題

最後但並非最不重要的是,我們非常歡迎在 官方 Ruby on Rails 論壇 上針對 Ruby on Rails 文件進行任何討論。