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
impl Notification
Sourcepub fn new(method: Method, params: Option<Value>) -> Self
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
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
impl Clone for Notification
Source§fn clone(&self) -> Notification
fn clone(&self) -> Notification
Returns a copy of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source
. Read moreSource§impl Debug for Notification
impl Debug for Notification
Source§impl<'de> Deserialize<'de> for Notification
impl<'de> Deserialize<'de> for Notification
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
Auto Trait Implementations§
impl Freeze for Notification
impl RefUnwindSafe for Notification
impl Send for Notification
impl Sync for Notification
impl Unpin for Notification
impl UnwindSafe for Notification
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more