pforge_runtime/
transport.rs

1//! Transport layer implementation
2//!
3//! This module provides transport creation based on configuration.
4
5use crate::{Error, Result};
6use pforge_config::TransportType;
7use pmcp::shared::{
8    OptimizedSseConfig, OptimizedSseTransport, StdioTransport, Transport, WebSocketConfig,
9    WebSocketTransport,
10};
11use std::time::Duration;
12
13/// Create a transport based on configuration
14pub fn create_transport(transport_type: &TransportType) -> Result<Box<dyn Transport>> {
15    match transport_type {
16        TransportType::Stdio => {
17            let transport = StdioTransport::new();
18            Ok(Box::new(transport))
19        }
20        TransportType::Sse => {
21            let config = OptimizedSseConfig {
22                url: "http://localhost:8080/sse".to_string(),
23                connection_timeout: Duration::from_secs(30),
24                keepalive_interval: Duration::from_secs(15),
25                max_reconnects: 5,
26                reconnect_delay: Duration::from_secs(1),
27                buffer_size: 100,
28                flush_interval: Duration::from_millis(100),
29                enable_pooling: true,
30                max_connections: 10,
31                enable_compression: false,
32            };
33            let transport = OptimizedSseTransport::new(config);
34            Ok(Box::new(transport))
35        }
36        TransportType::WebSocket => {
37            let url = "ws://localhost:8080/ws"
38                .parse()
39                .map_err(|e| Error::Handler(format!("Invalid WebSocket URL: {}", e)))?;
40
41            let config = WebSocketConfig {
42                url,
43                auto_reconnect: true,
44                reconnect_delay: Duration::from_secs(1),
45                max_reconnect_delay: Duration::from_secs(30),
46                max_reconnect_attempts: Some(5),
47                ping_interval: Some(Duration::from_secs(30)),
48                request_timeout: Duration::from_secs(10),
49            };
50            let transport = WebSocketTransport::new(config);
51            Ok(Box::new(transport))
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn test_create_stdio_transport() {
62        let transport = create_transport(&TransportType::Stdio);
63        assert!(transport.is_ok());
64        let t = transport.unwrap();
65        assert_eq!(t.transport_type(), "stdio");
66    }
67
68    #[tokio::test]
69    async fn test_create_sse_transport() {
70        let transport = create_transport(&TransportType::Sse);
71        assert!(transport.is_ok());
72    }
73
74    #[test]
75    fn test_create_websocket_transport() {
76        let transport = create_transport(&TransportType::WebSocket);
77        assert!(transport.is_ok());
78    }
79
80    // Note: SSE and WebSocket tests require server running, so they're integration tests
81}