actr_runtime/transport/
wire_builder.rs1use super::Dest; use super::error::NetworkResult;
9use super::manager::WireBuilder;
10use super::wire_handle::WireHandle;
11use crate::wire::webrtc::WebRtcCoordinator;
12use crate::wire::websocket::WebSocketConnection;
13use async_trait::async_trait;
14use std::sync::Arc;
15
16pub struct DefaultWireBuilderConfig {
18 pub websocket_url_template: Option<String>,
20
21 pub enable_webrtc: bool,
23
24 pub enable_websocket: bool,
26}
27
28impl Default for DefaultWireBuilderConfig {
29 fn default() -> Self {
30 Self {
31 websocket_url_template: None,
32 enable_webrtc: true,
33 enable_websocket: false, }
35 }
36}
37
38pub struct DefaultWireBuilder {
43 webrtc_coordinator: Option<Arc<WebRtcCoordinator>>,
45
46 websocket_url_template: Option<String>,
48
49 config: DefaultWireBuilderConfig,
51}
52
53impl DefaultWireBuilder {
54 pub fn new(
60 webrtc_coordinator: Option<Arc<WebRtcCoordinator>>,
61 config: DefaultWireBuilderConfig,
62 ) -> Self {
63 Self {
64 webrtc_coordinator,
65 websocket_url_template: config.websocket_url_template.clone(),
66 config,
67 }
68 }
69
70 fn build_websocket_url(&self, dest: &Dest) -> Option<String> {
72 let template = self.websocket_url_template.as_ref()?;
73
74 match dest {
75 Dest::Actor(actor_id) => {
76 let url = template.replace("{actor_id}", &actor_id.serial_number.to_string());
78 Some(url)
79 }
80 Dest::Shell | Dest::Local => {
81 None
84 }
85 }
86 }
87}
88
89#[async_trait]
90impl WireBuilder for DefaultWireBuilder {
91 async fn create_connections(&self, dest: &Dest) -> NetworkResult<Vec<WireHandle>> {
92 let mut connections = Vec::new();
93
94 if self.config.enable_websocket {
96 if let Some(url) = self.build_websocket_url(dest) {
97 tracing::debug!("🏭 [Factory] Create WebSocket Connect: {}", url);
98 let ws_conn = WebSocketConnection::new(url);
99 connections.push(WireHandle::WebSocket(ws_conn));
100 } else {
101 tracing::warn!(
102 "⚠️ [Factory] WebSocket enabled but no method construct build URL: {:?}",
103 dest
104 );
105 }
106 }
107
108 if self.config.enable_webrtc {
110 if let Some(coordinator) = &self.webrtc_coordinator {
111 if dest.is_actor() {
113 tracing::debug!("🏭 [Factory] Create WebRTC Connectto: {:?}", dest);
114 match coordinator.create_connection(dest).await {
115 Ok(webrtc_conn) => {
116 connections.push(WireHandle::WebRTC(webrtc_conn));
117 }
118 Err(e) => {
119 tracing::warn!(
120 "❌ [Factory] WebRTC ConnectCreatefailure: {:?}: {}",
121 dest,
122 e
123 );
124 }
126 }
127 } else {
128 tracing::debug!(
129 "ℹ️ [Factory] WebRTC not Support Shell item mark ,skip through "
130 );
131 }
132 } else {
133 tracing::warn!("⚠️ [Factory] WebRTC enabled but not Provide WebRtcCoordinator");
134 }
135 }
136
137 tracing::info!(
138 "✨ [Factory] as {:?} Create done {} Connect",
139 dest,
140 connections.len()
141 );
142
143 Ok(connections)
144 }
145}
146
147#[cfg(test)]
148mod tests {
149 use super::*;
150 use actr_protocol::ActrId;
151
152 #[test]
153 fn test_build_websocket_url() {
154 let config = DefaultWireBuilderConfig {
155 websocket_url_template: Some("ws://server:8080/actor/{actor_id}".to_string()),
156 enable_websocket: true,
157 enable_webrtc: false,
158 };
159
160 let factory = DefaultWireBuilder::new(None, config);
161
162 let mut actor_id = ActrId::default();
163 actor_id.serial_number = 12345;
164 let dest = Dest::Actor(actor_id);
165
166 let url = factory.build_websocket_url(&dest);
167 assert_eq!(url, Some("ws://server:8080/actor/12345".to_string()));
168 }
169
170 #[tokio::test]
171 async fn test_create_websocket_connection() {
172 use actr_protocol::ActrId;
173
174 let config = DefaultWireBuilderConfig {
175 websocket_url_template: Some("ws://localhost:8080".to_string()),
176 enable_websocket: true,
177 enable_webrtc: false,
178 };
179
180 let factory = DefaultWireBuilder::new(None, config);
181 let actor_id = ActrId::default();
183 let dest = Dest::actor(actor_id);
184
185 let connections = factory.create_connections(&dest).await.unwrap();
186 assert_eq!(connections.len(), 1);
187
188 if let WireHandle::WebSocket(_ws_conn) = &connections[0] {
189 } else {
191 panic!("Expected WebSocket connection");
192 }
193 }
194}