查看源码 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
中的某个启动函数启动,请参阅 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
连接的引用,由ssh:connect/3
返回。{channel_id,
ssh:channel_id/0
}
-ssh
通道的 ID,由 ssh_connection:session_channel/2,4 返回。
注意
此函数通常不由用户调用。用户仅当需要使用
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
。