Action Cable Channel
Base
通道提供將行為群組成群組到透過 WebSocket 連線進行通訊時邏輯單元的基礎結構。你可以將通道想成是控制器的一種形式,但除了單純回應訂閱者的直接要求外,它還能夠將內容推播給訂閱者。
Channel
實例是長佇留的。當連接使用者成為訂閱者時,將實例化一個通道物件,然後在使用者斷線之前持續運作。這可能是數秒、數分鐘、數小時,甚至數天。這表示你必須特別小心,不要在通道中進行任何會使記憶體使用量激增的傻事。參考會持續存在,因此不會像在每次請求後丟棄的控制器實例那樣被釋放。
長佇留通道(和連線)也表示你有責任確保資料的時效性。如果你保留對使用者的紀錄,但在保留參考期間變更了名稱,如果你沒有採取預防措施來避免,你可能會傳送過舊的資料。
長佇留通道實例的好處是你可以使用實例變數來保留與未來訂閱者要求可以互動的物件的參考。這裡有一個快速範例
class ChatChannel < ApplicationCable::Channel
def subscribed
@room = Chat::Room[params[:room_number]]
end
def speak(data)
@room.speak data, user: current_user
end
end
在消費者第一次訂閱通道時所建立的 Chat::Room 物件,只要消費者想要在房間中發言,speak 動作就會單純地使用該物件。
動作處理
與 ActionController::Base
的子類別不同,通道不會為其動作遵循 RESTful 限制表單。反之,Action Cable 會透過遠端程式呼叫模型來執行。你可以在通道上宣告任何公開的方法(選擇加上一個 data
參數),而此方法會自動對外公開,作為可以由客戶端呼叫的方法。
範例
class AppearanceChannel < ApplicationCable::Channel
def subscribed
@connection_token = generate_connection_token
end
def unsubscribed
current_user.disappear @connection_token
end
def appear(data)
current_user.appear @connection_token, on: data['appearing_on']
end
def away
current_user.away @connection_token
end
private
def generate_connection_token
SecureRandom.hex(36)
end
end
在此範例中,subscribed 及 unsubscribed 方法並不是可以呼叫的方法,因為它們已經在 ActionCable::Channel::Base
中宣告,但是 #appear
和 #away
可以。#generate_connection_token
也不是可以呼叫的方法,因為它是一個私人方法。你會看到 appear 可以接受一個資料參數,然後將它用於模型呼叫的一部份。#away
不會接受,因為它只是一個觸發動作。
另外請注意,在此範例中,current_user
是可用的,因為它已在連線中標示為識別屬性。上述的所有識別碼都會自動在通道實例上建立一個具有相同名稱的委派方法。
取消訂閱要求
一個通道可以透過在 subscribed
回呼中呼叫 reject
方法來取消訂閱要求
class ChatChannel < ApplicationCable::Channel
def subscribed
@room = Chat::Room[params[:room_number]]
reject unless current_user.can_access?(@room)
end
end
在此範例中,如果 current_user
無權存取聊天室,將會取消訂閱。在用戶端,當伺服器取消訂閱要求時,將會呼叫 Channel#rejected
回呼。
- A
- C
- D
- E
- M
- N
- P
- R
- S
- T
- U
- ActionCable::Channel::Callbacks
- ActionCable::Channel::PeriodicTimers
- ActionCable::Channel::Streams
- ActionCable::Channel::Naming
- ActionCable::Channel::Broadcasting
- ActiveSupport::Rescuable
屬性
[R] | connection | |
[R] | identifier | |
[R] | params |
類別公共方法
action_methods() 連結
來源: 顯示 | 在 GitHub 上
# File actioncable/lib/action_cable/channel/base.rb, line 128 def action_methods @action_methods ||= begin # All public instance methods of this class, including ancestors methods = (public_instance_methods(true) - # Except for public instance methods of Base and its ancestors ActionCable::Channel::Base.public_instance_methods(true) + # Be sure to include shadowed public instance methods of this class public_instance_methods(false)).uniq.map(&:to_s) methods.to_set end end
new(connection, identifier, params = {}) 連結
來源: 顯示 | 在 GitHub 上
# File actioncable/lib/action_cable/channel/base.rb, line 155 def initialize(connection, identifier, params = {}) @connection = connection @identifier = identifier @params = params # When a channel is streaming via pubsub, we want to delay the confirmation # transmission until pubsub subscription is confirmed. # # The counter starts at 1 because it's awaiting a call to #subscribe_to_channel @defer_subscription_confirmation_counter = Concurrent::AtomicFixnum.new(1) @reject_subscription = nil @subscription_confirmation_sent = nil delegate_connection_identifiers end
類別私人方法
clear_action_methods!() 連結
action_methods
已快取,有時需要更新。 ::clear_action_methods!
讓您可以這麼做,因此下次執行 action_methods
時,它們會重新計算。
來源: 顯示 | 在 GitHub 上
# File actioncable/lib/action_cable/channel/base.rb, line 144 def clear_action_methods! # :doc: @action_methods = nil end
method_added(name) 連結
當新增新的 action_method 時更新快取的 action_methods
。
來源: 顯示 | 在 GitHub 上
# File actioncable/lib/action_cable/channel/base.rb, line 149 def method_added(name) # :doc: super clear_action_methods! end
實體公共方法
perform_action(data) 連結
從傳遞的資料中擷取動作名稱,並透過頻道處理。此處理程序會確保所請求的動作是使用者在頻道上宣告的公開方法(因此不是 subscribed
類似於的回呼之一)。
來源: 顯示 | 在 GitHub 上
# File actioncable/lib/action_cable/channel/base.rb, line 175 def perform_action(data) action = extract_action(data) if processable_action?(action) payload = { channel_class: self.class.name, action: action, data: data } ActiveSupport::Notifications.instrument("perform_action.action_cable", payload) do dispatch_action(action, data) end else logger.error "Unable to process #{action_signature(action, data)}" end end
subscribe_to_channel() 連結
連結已新增至連線後會呼叫此方法,並確認或拒絕此訂閱。
來源: 顯示 | 在 GitHub 上
# File actioncable/lib/action_cable/channel/base.rb, line 190 def subscribe_to_channel run_callbacks :subscribe do subscribed end reject_subscription if subscription_rejected? ensure_confirmation_sent end