开始
让我们创建并运行我们的第一个actix应用程序。我们将创建一个新的Cargo项目,该项目依赖于actix然后运行应用程序。
在上一节中,我们已经安装了所需的Rust版本 现在让我们创建新的Cargo项目。
Ping actor
让我们来写第一个actix应用程序吧!首先创建一个新的基于二进制的Cargo项目并切换到新目录:
cargo new actor-ping --bincd actor-ping
现在,通过确保您的Cargo.toml包含以下内容,将actix添加为项目的依赖项:
[dependencies]actix = "0.7"
让我们创建一个接受Ping消息的actor,并使用处理的ping数进行响应。
actor是实现Actor trait的类型:
extern crate actix;use actix::prelude::*;struct MyActor {count: usize,}impl Actor for MyActor {type Context = Context<Self>;}fn main() {}
每个actor都有一个Context, 对于MyActor我们将使用Context<A>。有关actor上下文的更多信息,请参阅下一节。
现在我们需要定义actor需要接受的Message。消息可以是实现Messagetrait的任何类型。
extern crate actix;use actix::prelude::*;struct Ping(usize);impl Message for Ping {type Result = usize;}fn main() {}
Messagetrait的主要目的是定义结果类型。 Ping消息定义usize,表示任何可以接受Ping消息的actor都需要返回usize值。
最后,我们需要声明我们的actor MyActor可以接受Ping并处理它。为此,actor需要实现Handler <Ping> trait。
extern crate actix;use actix::prelude::*;struct MyActor {count: usize,}impl Actor for MyActor {type Context = Context<Self>;}struct Ping(usize);impl Message for Ping {type Result = usize;}impl Handler<Ping> for MyActor {type Result = usize;fn handle(&mut self, msg: Ping, ctx: &mut Context<Self>) -> Self::Result {self.count += msg.0;self.count}}fn main() {}
现在我们只需要启动我们的actor并向其发送消息。启动过程取决于actor的上下文实现。在我们的情况下可以使用Context <A>其基于tokio / future。我们可以用Actor :: start()开始它或者Actor :: create()。第一个是在可以立即创建actor实例时使用的。第二种方法用于我们在创建之前需要访问上下文对象的情况actor实例。对于MyActor actor,我们可以使用start()。
与actor的所有通信都通过一个address。你可以do_send一条消息无需等待响应,或send给具有特定消息的actor。start()和create()都返回一个address对象。
在下面的示例中,我们将创建一个MyActor actor并发送一条消息。
extern crate actix;extern crate futures;use futures::Future;use actix::prelude::*;struct MyActor {count: usize,}impl Actor for MyActor {type Context = Context<Self>;}struct Ping(usize);impl Message for Ping {type Result = usize;}impl Handler<Ping> for MyActor {type Result = usize;fn handle(&mut self, msg: Ping, ctx: &mut Context<Self>) -> Self::Result {self.count += msg.0;self.count}}fn main() {let system = System::new("test");// start new actorlet addr = MyActor{count: 10}.start();// send message and get future for resultlet res = addr.send(Ping(10));Arbiter::spawn(res.map(|res| {# System::current().stop();println!("RESULT: {}", res == 20);}).map_err(|_| ()));system.run();}
Ping示例位于示例中。
