Struct Notification

Source
pub struct Notification {
    pub jsonrpc: String,
    pub method: String,
    pub params: Option<Value>,
}
Expand description

JSON-RPC notification message (request without ID) JSON-RPC 通知消息(没有 ID 的请求)

Fields§

§jsonrpc: String

Protocol version (must be “2.0”) 协议版本(必须为 “2.0”)

§method: String

Notification method 通知方法

§params: Option<Value>

Optional parameters 可选参数

Implementations§

Source§

impl Notification

Source

pub fn new(method: Method, params: Option<Value>) -> Self

Creates a new notification 创建一个新的通知

Examples found in repository?
examples/ping_example.rs (line 216)
93async fn run_client() -> Result<()> {
94    // 跟踪会话中使用的请求 ID
95    // Track request IDs used in the session
96    let mut session_ids = HashSet::new();
97    let mut ping_count = 0;
98    let total_pings = 3;
99
100    // 配置客户端
101    // Configure client
102    let config = TransportConfig {
103        transport_type: TransportType::Http {
104            base_url: format!("http://{}", SERVER_URL),
105            auth_token: Some(AUTH_TOKEN.to_string()),
106        },
107        parameters: None,
108    };
109
110    // 创建客户端实例
111    // Create client instance
112    let factory = ClientTransportFactory;
113    let mut client = factory.create(config)?;
114
115    // 初始化客户端
116    // Initialize client
117    match timeout(CONNECTION_TIMEOUT, client.initialize()).await {
118        Ok(result) => result?,
119        Err(_) => {
120            return Err(mcprotocol_rs::Error::Transport(
121                "Client initialization timeout".into(),
122            ))
123        }
124    }
125    eprintln!("Client started");
126
127    // 发送 ping 请求并保持连接活跃
128    // Send ping requests and keep connection alive
129    let start_time = std::time::Instant::now();
130
131    while ping_count < total_pings {
132        // 检查是否接近服务器超时时间
133        // Check if approaching server timeout
134        if start_time.elapsed() > SERVER_TIMEOUT - Duration::from_secs(30) {
135            eprintln!("Approaching server timeout, ending session");
136            break;
137        }
138
139        // 发送 ping 请求
140        // Send ping request
141        let request_id = RequestId::String(format!("ping-{}", ping_count + 1));
142        let ping_request = Request::new(Method::Ping, None, request_id.clone());
143
144        // 验证请求 ID 的唯一性
145        // Validate request ID uniqueness
146        if !ping_request.validate_id_uniqueness(&mut session_ids) {
147            eprintln!("Request ID has already been used in this session");
148            break;
149        }
150
151        eprintln!("Sending ping request #{}", ping_count + 1);
152        client.send(Message::Request(ping_request.clone())).await?;
153
154        // 等待 pong 响应,带超时
155        // Wait for pong response with timeout
156        match timeout(PING_TIMEOUT, client.receive()).await {
157            Ok(Ok(Message::Response(response))) => {
158                if !request_id_matches(&request_id, &response.id) {
159                    eprintln!(
160                        "Received response with mismatched ID: expected {}, got {}",
161                        request_id_to_string(&request_id),
162                        request_id_to_string(&response.id)
163                    );
164                    continue;
165                }
166
167                if response.error.is_some() {
168                    eprintln!("Received error response: {:?}", response.error);
169                    break;
170                }
171                eprintln!("Received pong response #{}", ping_count + 1);
172            }
173            Ok(Ok(message)) => {
174                eprintln!("Unexpected message type: {:?}", message);
175                continue;
176            }
177            Ok(Err(e)) => {
178                eprintln!("Error receiving response: {}", e);
179                break;
180            }
181            Err(_) => {
182                eprintln!("Ping timeout for request #{}", ping_count + 1);
183                break;
184            }
185        }
186
187        ping_count += 1;
188        if ping_count < total_pings {
189            // 使用较短的间隔以避免服务器超时
190            // Use shorter interval to avoid server timeout
191            sleep(PING_INTERVAL.min(Duration::from_secs(30))).await;
192        }
193    }
194
195    // 发送关闭请求
196    // Send shutdown request
197    if ping_count == total_pings {
198        let shutdown_request = Request::new(
199            Method::Shutdown,
200            None,
201            RequestId::String("shutdown".to_string()),
202        );
203
204        if shutdown_request.validate_id_uniqueness(&mut session_ids) {
205            client.send(Message::Request(shutdown_request)).await?;
206
207            // 等待关闭响应
208            // Wait for shutdown response
209            match timeout(PING_TIMEOUT, client.receive()).await {
210                Ok(Ok(Message::Response(response))) => {
211                    if response.error.is_some() {
212                        eprintln!("Shutdown failed: {:?}", response.error);
213                    } else {
214                        // 发送退出通知
215                        // Send exit notification
216                        let exit_notification = Notification::new(Method::Exit, None);
217                        client
218                            .send(Message::Notification(exit_notification))
219                            .await?;
220                    }
221                }
222                Ok(Ok(_)) => eprintln!("Unexpected response type"),
223                Ok(Err(e)) => eprintln!("Error receiving shutdown response: {}", e),
224                Err(_) => eprintln!("Shutdown response timeout"),
225            }
226        } else {
227            eprintln!("Shutdown request ID has already been used in this session");
228        }
229    }
230
231    client.close().await?;
232    eprintln!("Client stopped");
233    Ok(())
234}
More examples
Hide additional examples
examples/lifecycle_client.rs (line 101)
11async fn main() -> Result<()> {
12    // 跟踪会话中使用的请求 ID
13    // Track request IDs used in the session
14    let mut session_ids = HashSet::new();
15
16    // 获取服务器程序路径
17    // Get server program path
18    let server_path = env::current_dir()?.join("target/debug/examples/lifecycle_server");
19
20    // 配置 Stdio 客户端
21    // Configure Stdio client
22    let config = TransportConfig {
23        transport_type: TransportType::Stdio {
24            server_path: Some(server_path.to_str().unwrap().to_string()),
25            server_args: None,
26        },
27        parameters: None,
28    };
29
30    // 创建客户端实例
31    // Create client instance
32    let factory = ClientTransportFactory;
33    let mut client = factory.create(config)?;
34
35    eprintln!("Client starting...");
36
37    // 初始化客户端
38    // Initialize client
39    client.initialize().await?;
40
41    // 发送初始化请求
42    // Send initialize request
43    let init_request = Request::new(
44        Method::Initialize,
45        Some(json!({
46            "protocolVersion": PROTOCOL_VERSION,
47            "capabilities": ClientCapabilities {
48                roots: None,
49                sampling: None,
50                experimental: None,
51            },
52            "clientInfo": ImplementationInfo {
53                name: "Example Client".to_string(),
54                version: "1.0.0".to_string(),
55            }
56        })),
57        RequestId::Number(1),
58    );
59
60    // 验证请求 ID 的唯一性
61    // Validate request ID uniqueness
62    if !init_request.validate_id_uniqueness(&mut session_ids) {
63        eprintln!("Request ID has already been used in this session");
64        return Ok(());
65    }
66
67    eprintln!("Sending initialize request...");
68    client.send(Message::Request(init_request)).await?;
69
70    // 等待初始化响应
71    // Wait for initialize response
72    match client.receive().await {
73        Ok(message) => {
74            match message {
75                Message::Response(response) => {
76                    if response.error.is_some() {
77                        eprintln!("Initialization failed: {:?}", response.error);
78                        return Ok(());
79                    }
80
81                    if let Some(result) = response.result {
82                        // 检查服务器版本和能力
83                        // Check server version and capabilities
84                        let server_version = result
85                            .get("protocolVersion")
86                            .and_then(|v| v.as_str())
87                            .unwrap_or("unknown");
88
89                        if server_version != PROTOCOL_VERSION {
90                            eprintln!(
91                                "Protocol version mismatch: expected {}, got {}",
92                                PROTOCOL_VERSION, server_version
93                            );
94                            return Ok(());
95                        }
96
97                        eprintln!("Server initialized with version: {}", server_version);
98
99                        // 发送初始化完成通知
100                        // Send initialized notification
101                        let init_notification = Notification::new(Method::Initialized, None);
102                        client
103                            .send(Message::Notification(init_notification))
104                            .await?;
105                        eprintln!("Sent initialized notification");
106
107                        // 模拟一些操作
108                        // Simulate some operations
109                        tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
110
111                        // 发送关闭请求
112                        // Send shutdown request
113                        eprintln!("Sending shutdown request...");
114                        let shutdown_request =
115                            Request::new(Method::Shutdown, None, RequestId::Number(2));
116
117                        // 验证请求 ID 的唯一性
118                        // Validate request ID uniqueness
119                        if !shutdown_request.validate_id_uniqueness(&mut session_ids) {
120                            eprintln!("Request ID has already been used in this session");
121                            return Ok(());
122                        }
123
124                        client.send(Message::Request(shutdown_request)).await?;
125
126                        // 等待关闭响应
127                        // Wait for shutdown response
128                        match client.receive().await {
129                            Ok(message) => {
130                                match message {
131                                    Message::Response(response) => {
132                                        if response.error.is_some() {
133                                            eprintln!("Shutdown failed: {:?}", response.error);
134                                            return Ok(());
135                                        }
136
137                                        // 发送退出通知
138                                        // Send exit notification
139                                        eprintln!("Sending exit notification...");
140                                        let exit_notification =
141                                            Notification::new(Method::Exit, None);
142                                        client
143                                            .send(Message::Notification(exit_notification))
144                                            .await?;
145                                    }
146                                    _ => eprintln!("Unexpected response type"),
147                                }
148                            }
149                            Err(e) => {
150                                eprintln!("Error receiving response: {}", e);
151                                return Ok(());
152                            }
153                        }
154                    }
155                }
156                _ => eprintln!("Unexpected message type"),
157            }
158        }
159        Err(e) => {
160            eprintln!("Error receiving response: {}", e);
161            return Ok(());
162        }
163    }
164
165    // 关闭客户端
166    // Close client
167    client.close().await?;
168    eprintln!("Client stopped");
169    Ok(())
170}

Trait Implementations§

Source§

impl Clone for Notification

Source§

fn clone(&self) -> Notification

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Notification

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Notification

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for Notification

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. 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
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

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

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

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.
Source§

impl<T> WithSubscriber for T

Source§

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
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

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

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T