檢視原始碼 ssh_client_channel 行為 (ssh v5.2.5)
SSH 服務(客戶端和伺服器)實作為透過 SSH 連線多工處理的通道,並透過 SSH 連線協定 通訊。此模組提供一個回呼 API,處理客戶端的通用通道方面,例如流量控制和關閉訊息。它讓回呼函式處理服務(應用程式)特定的部分。此行為也確保通道程序遵守 OTP 程序的原則,使其可以成為監督樹的一部分。這是實作將被新增至 ssh
應用程式監督樹的子系統之通道程序的必要條件。
注意
此模組取代 ssh_channel。
舊模組仍然可用於相容性,但不應該用於新的程式。舊模組除了修正一些錯誤外,將不再維護。
注意
當為守護進程實作
ssh
子系統時,請改用 -behaviour(ssh_server_channel) (取代 ssh_daemon_channel)。
請勿
此模組中的函式不應該在實作此行為的模組之外呼叫!
回呼逾時
回呼函式可以傳回的逾時值,其語意與 gen_server
中的語意相同。如果發生逾時,則會呼叫 handle_msg/2
為 handle_msg(timeout, State)。
摘要
回呼
當程式碼變更時轉換處理程序狀態。
處理透過呼叫 call/2,3 送出的訊息
處理透過呼叫 cast/2
送出的訊息。
處理傳送至通道的其他訊息,而非 SSH 連線協定、call 或 cast 訊息。
處理可能需要服務特定注意的 SSH 連線協定訊息。詳細資訊,請參閱 ssh_connection:event/0
。
如果初始化成功,則進行必要的初始化並傳回初始通道狀態。
當通道程序即將終止時,會呼叫此函式。在呼叫此函式之前,會呼叫 ssh_connection:close/2 (如果先前尚未呼叫)。此函式會執行任何必要的清除。當它傳回時,通道程序會以 Reason
原因終止。傳回值會被忽略。
函式
藉由傳送訊息並等待回覆到達,或發生逾時,對通道程序進行同步呼叫。通道會呼叫 Module:handle_call/3 來處理訊息。如果通道程序不存在,則會傳回 {error, closed}
。
傳送非同步訊息至通道程序,並立即傳回 ok,忽略目的地節點或通道程序是否存在。通道會呼叫 Module:handle_cast/2 來處理訊息。
使現有程序成為 ssh_client_channel
(取代 ssh_channel) 程序。
啟動客戶端通道。
當回覆無法在 Module:handle_call/3 的傳回值中定義時,通道可以使用此函式來傳送回覆至呼叫 call/[2,3]
的客戶端。
啟動處理 SSH 通道的程序。它由 ssh
守護進程在內部呼叫,或由 ssh
客戶端實作明確呼叫。行為會將 trap_exit
旗標設定為 true
。
類型
回呼
-callback code_change(OldVsn :: term() | {down, term()}, State :: term(), Extra :: term()) -> {ok, NewState :: term()} | {error, Reason :: term()}.
當程式碼變更時轉換處理程序狀態。
當客戶端通道要在版本升級或降級期間更新其內部狀態時,會呼叫此函式,也就是說,當 appup
檔案中給定指令 {update,Module,Change,...}
,其中 Change={advanced,Extra}
時。有關詳細資訊,請參閱系統文件中的第 9.11.6 節版本處理指令。
注意
根據 OTP 版本概念的軟升級對於伺服器端而言並非直接進行,因為子系統通道程序是由
ssh
應用程式衍生並因此新增至其監督樹。如果回呼函式可以處理兩個版本的狀態,則可以在升級使用者應用程式時升級子系統通道,但是此函式不能以正常方式使用。
-callback handle_call(Request :: term(), From :: {pid(), Tag :: term()}, State :: term()) -> {reply, Reply :: term(), NewState :: term()} | {reply, Reply :: term(), NewState :: term(), timeout() | hibernate} | {noreply, NewState :: term()} | {noreply, NewState :: term(), timeout() | hibernate} | {stop, Reason :: term(), Reply :: term(), NewState :: term()} | {stop, Reason :: term(), NewState :: term()}.
處理透過呼叫 call/2,3 送出的訊息
有關逾時的更詳細資訊,請參閱回呼逾時一節。
-callback handle_cast(Request :: term(), State :: term()) -> {noreply, NewState :: term()} | {noreply, NewState :: term(), timeout() | hibernate} | {stop, Reason :: term(), NewState :: term()}.
處理透過呼叫 cast/2
送出的訊息。
有關逾時的更詳細資訊,請參閱回呼逾時一節。
-callback handle_msg(Msg :: term(), State :: term()) -> {ok, State :: term()} | {stop, ChannelId :: ssh:channel_id(), State :: term()}.
處理傳送至通道的其他訊息,而非 SSH 連線協定、call 或 cast 訊息。
此函式應該處理可能的 Erlang 'EXIT' 訊息,並且所有通道都應處理以下訊息。
{ssh_channel_up,
ssh:channel_id/0
,
ssh:connection_ref/0
}
- 這是通道接收的第一個訊息。它會在init/1
函式成功傳回之前傳送。如果伺服器想要在未先接收到來自用戶端的訊息的情況下將訊息傳送至用戶端,這特別有用。如果該訊息對於您的特定情境沒有用處,請立即傳回{ok, State}
來忽略它。
-callback handle_ssh_msg(ssh_connection:event(), State :: term()) -> {ok, State :: term()} | {stop, ChannelId :: ssh:channel_id(), State :: term()}.
處理可能需要服務特定注意的 SSH 連線協定訊息。詳細資訊,請參閱 ssh_connection:event/0
。
以下訊息由 ssh_client_channel
行為處理。
{closed,
ssh:channel_id/0
}
- 如果尚未傳送此訊息,則通道行為會將關閉訊息傳送至另一端。然後它會以原因normal
終止通道。
-callback init(Args :: term()) -> {ok, State :: term()} | {ok, State :: term(), timeout() | hibernate} | {stop, Reason :: term()} | ignore.
如果初始化成功,則進行必要的初始化並傳回初始通道狀態。
有關逾時的更詳細資訊,請參閱回呼逾時一節。
-callback terminate(Reason :: normal | shutdown | {shutdown, term()} | term(), State :: term()) -> term().
當通道程序即將終止時,會呼叫此函式。在呼叫此函式之前,會呼叫 ssh_connection:close/2 (如果先前尚未呼叫)。此函式會執行任何必要的清除。當它傳回時,通道程序會以 Reason
原因終止。傳回值會被忽略。
函式
-spec call(ChannelRef, Msg) -> Reply | {error, Reason} when ChannelRef :: pid(), Msg :: term(), Reply :: term(), Reason :: closed | timeout.
等同於 call/3
。
-spec call(ChannelRef, Msg, Timeout) -> Reply | {error, Reason} when ChannelRef :: pid(), Msg :: term(), Timeout :: timeout(), Reply :: term(), Reason :: closed | timeout.
藉由傳送訊息並等待回覆到達,或發生逾時,對通道程序進行同步呼叫。通道會呼叫 Module:handle_call/3 來處理訊息。如果通道程序不存在,則會傳回 {error, closed}
。
傳送非同步訊息至通道程序,並立即傳回 ok,忽略目的地節點或通道程序是否存在。通道會呼叫 Module:handle_cast/2 來處理訊息。
-spec enter_loop(State) -> _ when State :: term().
使現有程序成為 ssh_client_channel
(取代 ssh_channel) 程序。
不傳回,而是呼叫程序進入 ssh_client_channel
(取代 ssh_channel) 程序接收迴圈,並成為 ssh_client_channel
程序。程序必須已使用 proc_lib
中的其中一個 start 函式啟動,請參閱 STDLIB 中的 proc_lib
手冊頁。使用者負責程序的任何初始化,並且必須呼叫 init/1
。
-spec init(Options) -> {ok, State} | {ok, State, Timeout} | {stop, Reason} when Options :: [[{Option :: term(), Value :: term()}]], State :: term(), Timeout :: timeout(), Reason :: term().
啟動客戶端通道。
必須存在以下選項
{channel_cb, atom()}
- 實作通道行為的模組。{init_args(), list()}
- 回呼模組init
函數的參數列表。{cm,
ssh:connection_ref/0
}
- 由ssh:connect/3
返回的ssh
連線參考。{channel_id,
ssh:channel_id/0
}
- 由 ssh_connection:session_channel/2,4 返回的ssh
通道 ID。
注意
此函數通常不由使用者呼叫。只有在需要使用
proc_lib
啟動通道進程,而不是呼叫start/4
或start_link/4
時,使用者才需要呼叫此函數。
當回覆無法在 Module:handle_call/3 的傳回值中定義時,通道可以使用此函式來傳送回覆至呼叫 call/[2,3]
的客戶端。
Client
必須是提供給回呼函數 handle_call/3
的 From
參數。 Reply
是一個任意的項,它會作為 [call/[2,3]](call/2
) 的返回值返回給客戶端。
-spec start(SshConnection, ChannelId, ChannelCb, CbInitArgs) -> {ok, ChannelRef} | {error, Reason :: term()} when SshConnection :: ssh:connection_ref(), ChannelId :: ssh:channel_id(), ChannelCb :: atom(), CbInitArgs :: [term()], ChannelRef :: pid().
等同於 start_link/4
。
-spec start_link(SshConnection, ChannelId, ChannelCb, CbInitArgs) -> {ok, ChannelRef} | {error, Reason :: term()} when SshConnection :: ssh:connection_ref(), ChannelId :: ssh:channel_id(), ChannelCb :: atom(), CbInitArgs :: [term()], ChannelRef :: pid().
啟動處理 SSH 通道的程序。它由 ssh
守護進程在內部呼叫,或由 ssh
客戶端實作明確呼叫。行為會將 trap_exit
旗標設定為 true
。