Skip to main content

BackendConn

Struct BackendConn 

Source
pub struct BackendConn {
    pub user_id: AtomicU32,
    pub client_ver: u16,
    /* private fields */
}
Expand description

后端连接

Fields§

§user_id: AtomicU32§client_ver: u16

Implementations§

Source§

impl BackendConn

Source

pub async fn request_for_test( &self, cmd_id: u16, body: Vec<u8>, ) -> Result<NNFrame>

Test-only transport probe used by the duplex mock-backend canary.

This deliberately has a different name from the production primitive, and is absent unless test-util is explicitly enabled.

Source§

impl BackendConn

Source§

impl BackendConn

Source

pub const CONNECT_TIMEOUT: Duration

连接 TCP 的超时时间。

Linux 默认 tcp_syn_retries=6TcpStream::connect 等到 ETIMEDOUT 需要约 127 秒——用户启动 opend 时如果选到一个不通的 IP 就卡 2 分钟后 才报错 offline mode(某位 Rocky Linux 用户踩过)。加 10s 超时快速失败, 让上层(bridge.rs 的 connect 循环)有机会 fallback 到下一个候选 IP。

Source

pub const CLIENT_VER_FTGTW: u16 = 1031

Backend 侧可识别的 Rust OpenD 固定客户端版本号。

C++ 同时把 AppConfig::GetClientVersion() 写入 protocol header 与 ReqEncryptData.client_ex_ver;为便于后台识别,Rust OpenD 于 2026-07-14 将识别版本提升为 1031。该身份在首次建连和鉴权请求发出前必须已知, 不能从服务端动态配置取得;尚未识别 1031 的 backend 环境可能拒绝登录。 若后台重新分配版本, 只更新本常量,并由契约测试保证所有 wire/HTTP 出口同步变化。 Ref: f3c/FTNet/Src/ftnet/channel/impl/protocol_header.cpp:25-32 and f3c/FTlogin/Src/ftlogin/login/logger.cpp:304-310.

Source

pub async fn connect( addr: &str, push_callback: PushCallback, protocol_identity: BackendProtocolIdentity, ) -> Result<Self>

连接到后端服务器(带 10s 超时)

Source

pub async fn connect_race( addrs: &[String], push_callback: PushCallback, protocol_identity: BackendProtocolIdentity, ) -> Result<(Self, String)>

并发连接多个候选地址,谁先通用谁(对齐 C++ connector.cpp:175-189 ConnectStrategyAddr 的 concurrency_ip 语义)。

  • 每个候选独立带 CONNECT_TIMEOUT(10s)超时
  • 第一个 Ok(stream) 胜出,其余 pending task drop 时会关闭半连接
  • 全部失败返回最后一个错误

返回 (BackendConn, winner_addr),调用方用 winner_addr 做登录协议里的 host_ip/host_port 字段。

Source

pub fn from_duplex( stream: DuplexStream, push_callback: PushCallback, protocol_identity: BackendProtocolIdentity, ) -> Self

v1.4.70 D1: test-only 从 tokio::io::DuplexStream 构造 BackendConn

用于 integration tests(crates/futu-gateway/tests/common/mock_backend.rs) 替代真 TcpStream。生产路径通过 connect()from_stream() 不变。

Source

pub const fn protocol_identity(&self) -> BackendProtocolIdentity

Source

pub fn set_session_key(&self, key: Vec<u8>)

设置 session key(登录成功后调用)。接受变长字节,16/24/32 分别对应 AES-128/192/256。对齐 C++ Logger::session_key_std::string, 长度取决于服务端下发的 RspEncryptData.session_key 字段原始长度。

Source

pub fn set_sec_data(&self, val: u32)

设置 sec_data 初始值(登录成功后调用)

Source

pub fn apply_login_sec_data(&self, val: Option<u32>)

应用登录响应里的 sec_data。

C++ 只有在 RspEncryptData.has_sec_data() 时更新 secure_num_; 字段缺失时保留当前计数,避免 reconnect/login 响应裁剪时把安全数回退。

Ref: f3c/FTlogin/Src/ftlogin/login/logger.cpp:553-555.

Source

pub fn set_client_ip(&self, ip: String)

设置登录响应里的客户端外网 IP。

Source

pub fn client_ip(&self) -> String

读取登录响应里的客户端外网 IP。

Source

pub fn connection_generation(&self) -> u64

Immutable identity of this transport instance, included with every backend push so consumers can reject delivery from a retired route.

Source

pub fn pause_writer_admission_for_test(&self) -> LifecyclePauseHook

Source

pub fn is_connected(&self) -> bool

Source

pub fn subscribe_connection_state(&self) -> Receiver<bool>

Subscribe to low-level connection liveness changes.

C++ FTLogin publishes a connection-closed event immediately (GTWCmdAndPushReply::OMEvProc_ConnClosed) and lets the gateway enter reconnecting state without waiting for a later business request. Rust uses this watch channel to wake the reconnect monitor as soon as the recv/send task marks the TCP channel disconnected.

Source

pub fn mark_disconnected_for_reconnect(&self, reason: &'static str)

Mark this connection disconnected so owner-side reconnect loops stop routing business requests through a stale session.

Used when a higher-level channel event invalidates the session semantics even if the TCP socket has not closed yet. C++ channel state transitions publish disconnect/re-establish events; Rust exposes the same liveness edge through the existing connection-state watch channel.

Trait Implementations§

Source§

impl Drop for BackendConn

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more