60个版本
0.13.5 | 2024年6月9日 |
---|---|
0.13.3 | 2024年2月7日 |
0.13.1 | 2023年8月30日 |
0.13.0 | 2022年3月1日 |
0.3.3 | 2017年11月21日 |
#82 in 异步
312,504 每月下载量
用于 少于 277 crates
235KB
5K SLoC
文档
特性
- 异步和同步actor
- 本地/线程上下文中的actor通信
- 使用 futures 处理异步消息
- Actor监督
- 类型化消息(无
Any
类型) - 在稳定的Rust 1.68+上运行
用法
要使用 actix
,将以下内容添加到您的 Cargo.toml
[dependencies]
actix = "0.13"
初始化Actix
为了使用actix,您首先需要创建一个 System
。
fn main() {
let system = actix::System::new();
system.run();
}
Actix使用 Tokio 运行时。 System::new()
创建一个新的事件循环。 System.run()
启动Tokio事件循环,一旦 System
actor收到 SystemExit
消息,则结束。
实现Actor
为了定义actor,您需要定义一个结构体并使其实现 Actor
trait。
use actix::{Actor, Context, System};
struct MyActor;
impl Actor for MyActor {
type Context = Context<Self>;
fn started(&mut self, _ctx: &mut Self::Context) {
println!("I am alive!");
System::current().stop(); // <- stop system
}
}
fn main() {
let system = System::new();
let _addr = system.block_on(async { MyActor.start() });
system.run().unwrap();
}
启动新actor是通过 Actor trait 的 start
和 create
方法实现的。它提供了多种创建actor的方式;有关详细信息,请参阅文档。您可以实现Actor trait的 started
、stopping
和 stopped
方法。 started
在actor启动时被调用,而 stopping
在actor完成时被调用。有关actor生命周期的更多信息,请参阅API文档。
处理消息
演员通过发送消息与其他演员进行通信。在actix中,所有消息都是有类型的。让我们定义一个简单的带有两个 usize
参数和一个将接受此消息并返回两个数字之和的演员的 Sum
消息。在这里,我们使用 #[actix::main]
属性作为启动我们的 System
和驱动主函数的更简单方式,这样我们就可以轻松地 .await
来自 Actor
的响应。
use actix::prelude::*;
// this is our Message
// we have to define the response type (rtype)
#[derive(Message)]
#[rtype(usize)]
struct Sum(usize, usize);
// Actor definition
struct Calculator;
impl Actor for Calculator {
type Context = Context<Self>;
}
// now we need to implement `Handler` on `Calculator` for the `Sum` message.
impl Handler<Sum> for Calculator {
type Result = usize; // <- Message response type
fn handle(&mut self, msg: Sum, _ctx: &mut Context<Self>) -> Self::Result {
msg.0 + msg.1
}
}
#[actix::main] // <- starts the system and block until future resolves
async fn main() {
let addr = Calculator.start();
let res = addr.send(Sum(10, 5)).await; // <- send message and get future for result
match res {
Ok(result) => println!("SUM: {}", result),
_ => println!("Communication to the actor has failed"),
}
}
所有与演员的通信都通过一个 Addr
对象进行。你可以发送一个消息而不等待响应,或者你可以发送一个特定消息给演员。 Message
特性定义了消息的结果类型。
演员状态和特定消息的订阅
你可能已经注意到,Actor
和 Handler
特性的方法接受 &mut self
,因此你可以在演员中存储任何东西,并在必要时对其进行修改。
地址对象需要一个演员类型,但如果我们只想向一个可以处理该消息的演员发送特定消息,我们可以使用 Recipient
接口。让我们创建一个新的使用 Recipient
的演员。
use actix::prelude::*;
use std::time::Duration;
#[derive(Message)]
#[rtype(result = "()")]
struct Ping {
pub id: usize,
}
// Actor definition
struct Game {
counter: usize,
name: String,
recipient: Recipient<Ping>,
}
impl Actor for Game {
type Context = Context<Game>;
}
// simple message handler for Ping message
impl Handler<Ping> for Game {
type Result = ();
fn handle(&mut self, msg: Ping, ctx: &mut Context<Self>) {
self.counter += 1;
if self.counter > 10 {
System::current().stop();
} else {
println!("[{0}] Ping received {1}", self.name, msg.id);
// wait 100 nanoseconds
ctx.run_later(Duration::new(0, 100), move |act, _| {
act.recipient.do_send(Ping { id: msg.id + 1 });
});
}
}
}
fn main() {
let system = System::new();
system.block_on(async {
// To create a cyclic game link, we need to use a different constructor
// method to get access to its recipient before it starts.
let _game = Game::create(|ctx| {
// now we can get an address of the first actor and create the second actor
let addr = ctx.address();
let addr2 = Game {
counter: 0,
name: String::from("Game 2"),
recipient: addr.recipient(),
}
.start();
// let's start pings
addr2.do_send(Ping { id: 10 });
// now we can finally create first actor
Game {
counter: 0,
name: String::from("Game 1"),
recipient: addr2.recipient(),
}
});
});
// let the actors all run until they've shut themselves down
system.run().unwrap();
}
聊天示例
查看这个 聊天示例,它展示了在客户端/服务器网络服务中更全面的用法。
贡献
欢迎所有贡献,如果你有功能请求,请毫不犹豫地提出问题!
许可证
本项目受以下任一许可证的许可:
- Apache License,版本 2.0,(LICENSE-APACHE 或 https://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可证(LICENSE-MIT 或 https://opensource.org/licenses/MIT)
任选其一。
行为准则
向 actix 存储库的贡献是在贡献者协约的条款下组织的。Actix 团队承诺将介入以维护该行为准则。
依赖项
~4–13MB
~135K SLoC