1 个不稳定版本
0.1.0 | 2023年10月2日 |
---|
#21 in #message-passing
用于 2 crate
24KB
213 行
微消息传递库
ump-ng crate 是一个简单的客户端/服务器消息传递库,用于进程内通信。其主要目的是允许跨异步/非异步通信(对于服务器和客户端端点)。
ump-ng 与 ump 类似,但它具有单向消息传递操作。
lib.rs
:
ump-ng(下一代微消息传递)是一个在线程/任务之间传递消息的库。它与 ump
库类似,但增加了单向消息传递原语。
ump(-ng) 的主要目的是创建简单的 RPC 类设计,但是在进程内的线程/任务之间,而不是在网络上的进程之间。
高级使用概述
应用程序调用 channel
来创建一个由 Server
和 Client
组成的连接对。
服务器调用 [Server::wait()
]/[Server::async_wait()
],它阻塞并等待来自客户端的消息。
客户端(在单独的线程或任务中)调用 [Client::post()
] 向服务器发送单向消息,或 [Client::req()
]/ [Client::areq()
] 向服务器发送消息并等待回复。
服务器的 wait 调用返回一个 post 消息或一个包含消息和用于向客户端发送回复的 ReplyContext
的 request 消息。
在处理完应用程序定义的消息后,服务器必须在返回的回复上下文对象上调用 [ReplyContext::reply()
],以向客户端返回回复消息。
通常情况下,服务器会再次调用wait以等待来自客户端的下一个消息。
客户端收到来自服务器的回复并对其进行处理。
示例
use std::thread;
use ump_ng::{channel, MsgType};
let (server, client) = channel::<String, String, String, ()>();
let server_thread = thread::spawn(move || {
// Wait for data to arrive from a client
loop {
println!("Server waiting for message ..");
match server.wait().unwrap() {
MsgType::Put(data) => {
println!("Server received Put: '{}'", data);
}
MsgType::Request(data, rctx) => {
println!("Server received Request: '{}'", data);
// Process data from client
// Reply to client
let reply = format!("Hello, {}!", data);
println!("Server replying '{}'", reply);
rctx.reply(reply);
break;
}
}
}
println!("Server done");
});
let msg = String::from("Client");
println!("Client putting '{}'", msg);
let reply = client.post(msg).unwrap();
let msg = String::from("Client");
println!("Client requesting '{}'", msg);
let reply = client.req(msg).unwrap();
println!("Client received reply '{}'", reply);
println!("Client done");
server_thread.join().unwrap();
在实际应用中,send/reply类型可能是用于指示命令/返回类型及其相关数据的枚举(enum
)。在channel
的第三个类型参数是一个错误类型,可以用于明确地将错误传递回发送者。
语义
有一些可能有用的语义特性值得了解,但其中一些应该谨慎使用。本节将描述一些你可以信赖的语义,以及一些你应该小心依赖的语义。
稳定的不变量
这些是在未来版本中不应改变的行为。
- 回复上下文与
Server
上下文无关。这对于服务器线程来说有一些有用的含义,因为服务器线程会创建单独的线程来处理消息并返回回复:当有客户端正在等待回复时,服务器可以安全地终止(隐含:当有回复上下文正在传输时,服务器可以安全地终止)。 - 克隆的客户端与其原始客户端配对,但在其他所有方面,克隆和原始客户端都是相互独立的。
- 客户端可以被移动到新的线程。
- 可以组合任何同步/异步服务器/客户端的排列。当可用时,
async
代码必须使用异步方法变体。
不稳定的变量
这些是在当前版本中你可以信赖会工作,但它们只是当前实现的一个副作用。如果可能,请避免依赖这些。
- 单个客户端可以从两个不同的线程中使用。如果将
Client
对象放入Arc中,克隆并传递给另一个线程/任务,则克隆和原始对象可以同时使用。在将来,这可能不允许。建议创建客户端的新克隆。 - Put/Request消息按照它们添加到队列的顺序到达。在未来的版本中,一种类型可能比另一种类型具有更高的优先级。
依赖项
~1.1–6MB
~26K SLoC