unity_mirror_rs/mirror/
transport.rs

1use crate::commons::RevelArc;
2use once_cell::sync::Lazy;
3use std::fmt::{Display, Formatter};
4use std::hash::{Hash, Hasher};
5use std::ops::{Deref, DerefMut};
6
7pub enum TransportError {
8    None,
9    DnsResolve,       // 无法解析主机名
10    Refused,          // 连接被另一端拒绝。服务器已满等
11    Timeout,          // ping 超时或死链接
12    Congestion,       // 消息数量超过传输/网络可以处理的数量
13    InvalidReceive,   // 接收无效数据包(可能是故意攻击)
14    InvalidSend,      // 用户尝试发送无效数据
15    ConnectionClosed, // 连接自愿关闭或非自愿丢失
16    Unexpected,       // 意外错误/异常,需要修复。
17}
18
19#[derive(Debug, PartialEq, Eq, Clone, Copy)]
20#[repr(u8)]
21pub enum TransportChannel {
22    Reliable = 1,
23    Unreliable = 2,
24}
25
26impl Hash for TransportChannel {
27    fn hash<H: Hasher>(&self, state: &mut H) {
28        state.write_u8(*self as u8)
29    }
30}
31
32impl Into<TransportChannel> for i32 {
33    fn into(self) -> TransportChannel {
34        match self {
35            2 => TransportChannel::Unreliable,
36            _ => TransportChannel::Reliable,
37        }
38    }
39}
40
41impl Display for TransportError {
42    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
43        match self {
44            TransportError::DnsResolve => write!(f, "DNS 解析错误"),
45            TransportError::Refused => write!(f, "连接被拒绝"),
46            TransportError::Timeout => write!(f, "连接超时"),
47            TransportError::Congestion => write!(f, "消息数量超过传输/网络可以处理的数量"),
48            TransportError::InvalidReceive => write!(f, "接收无效数据包(可能是故意攻击)"),
49            TransportError::InvalidSend => write!(f, "用户尝试发送无效数据"),
50            TransportError::ConnectionClosed => write!(f, "连接自愿关闭"),
51            TransportError::Unexpected => write!(f, "意外错误/异常,需要修复。"),
52            TransportError::None => write!(f, ""),
53        }
54    }
55}
56
57static mut TRANSPORT_STATIC: Lazy<TransportStatic> = Lazy::new(|| TransportStatic { active: TransportStaticAction(None) });
58
59pub struct TransportStaticAction(Option<RevelArc<Box<dyn Transport>>>);
60
61impl From<RevelArc<Box<dyn Transport>>> for TransportStaticAction {
62    fn from(value: RevelArc<Box<dyn Transport>>) -> Self {
63        TransportStaticAction(Some(value))
64    }
65}
66
67impl Deref for TransportStaticAction {
68    type Target = RevelArc<Box<dyn Transport>>;
69    fn deref(&self) -> &Self::Target {
70        #[allow(static_mut_refs)]
71        self.0.as_ref().unwrap_or_else(|| {
72            panic!("Transport not initialized. Call init_transport_manager first.")
73        })
74    }
75}
76
77impl DerefMut for TransportStaticAction {
78    fn deref_mut(&mut self) -> &mut Self::Target {
79        #[allow(static_mut_refs)]
80
81        self.0.as_mut().unwrap_or_else(|| {
82            panic!("Transport not initialized. Call init_transport_manager first.")
83        })
84    }
85}
86
87pub struct TransportStatic {
88    pub(crate) active: TransportStaticAction,
89}
90
91pub struct TransportManager;
92
93impl Deref for TransportManager {
94    type Target = TransportStatic;
95    fn deref(&self) -> &Self::Target {
96        #[allow(static_mut_refs)]
97        unsafe {
98            &TRANSPORT_STATIC
99        }
100    }
101}
102
103impl DerefMut for TransportManager {
104    fn deref_mut(&mut self) -> &mut Self::Target {
105        #[allow(static_mut_refs)]
106        unsafe {
107            &mut TRANSPORT_STATIC
108        }
109    }
110}
111
112// impl TransportManager {
113//     pub fn active(&self) -> &'static mut Box<dyn Transport> {
114//         #[allow(static_mut_refs)]
115//         unsafe {
116//             TRANSPORT.as_mut().unwrap_or_else(|| {
117//                 panic!("Transport not initialized. Call init_transport_manager first.")
118//             })
119//         }
120//     }
121// }
122
123pub struct CallbackProcessor {
124    pub on_server_connected: fn(u64),
125    pub on_server_connected_with_address: fn(u64, &str),
126    pub on_server_data_received: fn(u64, &[u8], TransportChannel),
127    pub on_server_data_sent: fn(u64, &[u8], TransportChannel),
128    pub on_server_error: fn(u64, TransportError, &str),
129    pub on_server_transport_exception: fn(u64, Box<dyn std::error::Error>),
130    pub on_server_disconnected: fn(u64),
131}
132
133pub trait Transport {
134    fn init(&mut self, callback_processor: CallbackProcessor);
135    /// <summary>此传输在当前平台可用吗?</summary>
136    fn available(&self) -> bool;
137    /// <summary>此传输是否已加密以实现安全通信?</summary>
138    fn is_encrypted(&self) -> bool {
139        false
140    }
141    /// <summary>如果加密,使用哪种密码?</summary>
142    fn encryption_cipher(&self) -> String {
143        "".to_string()
144    }
145    /// <summary>以 Uri 形式返回服务器地址。</summary>
146    // 适用于 NetworkDiscovery。
147    fn server_uri(&self) -> http::Uri;
148    /// <summary>如果服务器当前正在监听连接,则为 True。</summary>
149    fn server_active(&self) -> bool;
150    /// <summary>开始监听连接。</summary>
151    fn server_start(&mut self, _: (&str, u16));
152    /// <summary>通过给定的渠道向客户端发送消息。</summary>
153    fn server_send(&self, connection_id: u64, segment: &[u8], channel_id: TransportChannel);
154    /// <summary>断开客户端与服务器的连接。</summary>
155    fn server_disconnect(&self, connection_id: u64);
156    /// <summary>获取服务器上的客户端地址。</summary>
157    // 可用于游戏管理员 IP 禁令等。
158    fn server_get_client_address(&self, connection_id: u64) -> Option<String>;
159    /// <summary>停止监听并断开所有连接。</summary>
160    fn server_stop(&self);
161    /// <summary>给定通道的最大消息大小。</summary>
162    // 不同的通道通常具有不同的大小,范围从 MTU 到几兆字节。
163    // 需要始终返回一个值,即使传输未运行或可用,因为它需要进行初始化。
164    fn get_max_packet_size(&self, channel_id: TransportChannel) -> usize;
165    /// <summary>建议为此传输设置批处理阈值。</summary>
166    // 默认使用 GetMaxPacketSize。
167    // 某些传输(如 kcp)支持较大的最大数据包大小,但不应一直用于批处理,因为它们最终会变得太慢(队头阻塞等)。
168    fn get_batch_threshold(&self, channel_id: TransportChannel) -> usize {
169        self.get_max_packet_size(channel_id)
170    }
171
172    fn server_early_update(&self);
173    fn server_late_update(&self);
174    fn shutdown(&self);
175    fn on_destroy(&self) {
176        self.shutdown()
177    }
178}