开始

让我们创建并运行我们的第一个actix应用程序。我们将创建一个新的Cargo项目,该项目依赖于actix然后运行应用程序。

在上一节中,我们已经安装了所需的Rust版本 现在让我们创建新的Cargo项目。

Ping actor

让我们来写第一个actix应用程序吧!首先创建一个新的基于二进制的Cargo项目并切换到新目录:

  1. cargo new actor-ping --bin
  2. cd actor-ping

现在,通过确保您的Cargo.toml包含以下内容,将actix添加为项目的依赖项:

  1. [dependencies]
  2. actix = "0.7"

让我们创建一个接受Ping消息的actor,并使用处理的ping数进行响应。

actor是实现Actor trait的类型:

  1. extern crate actix;
  2. use actix::prelude::*;
  3. struct MyActor {
  4. count: usize,
  5. }
  6. impl Actor for MyActor {
  7. type Context = Context<Self>;
  8. }
  9. fn main() {}

每个actor都有一个Context, 对于MyActor我们将使用Context<A>。有关actor上下文的更多信息,请参阅下一节。

现在我们需要定义actor需要接受的Message。消息可以是实现Messagetrait的任何类型。

  1. extern crate actix;
  2. use actix::prelude::*;
  3. struct Ping(usize);
  4. impl Message for Ping {
  5. type Result = usize;
  6. }
  7. fn main() {}

Messagetrait的主要目的是定义结果类型。 Ping消息定义usize,表示任何可以接受Ping消息的actor都需要返回usize值。

最后,我们需要声明我们的actor MyActor可以接受Ping并处理它。为此,actor需要实现Handler <Ping> trait。

  1. extern crate actix;
  2. use actix::prelude::*;
  3. struct MyActor {
  4. count: usize,
  5. }
  6. impl Actor for MyActor {
  7. type Context = Context<Self>;
  8. }
  9. struct Ping(usize);
  10. impl Message for Ping {
  11. type Result = usize;
  12. }
  13. impl Handler<Ping> for MyActor {
  14. type Result = usize;
  15. fn handle(&mut self, msg: Ping, ctx: &mut Context<Self>) -> Self::Result {
  16. self.count += msg.0;
  17. self.count
  18. }
  19. }
  20. fn main() {}

现在我们只需要启动我们的actor并向其发送消息。启动过程取决于actor的上下文实现。在我们的情况下可以使用Context <A>其基于tokio / future。我们可以用Actor :: start()开始它或者Actor :: create()。第一个是在可以立即创建actor实例时使用的。第二种方法用于我们在创建之前需要访问上下文对象的情况actor实例。对于MyActor actor,我们可以使用start()

与actor的所有通信都通过一个address。你可以do_send一条消息无需等待响应,或send给具有特定消息的actorstart()create()都返回一个address对象。

在下面的示例中,我们将创建一个MyActor actor并发送一条消息。

  1. extern crate actix;
  2. extern crate futures;
  3. use futures::Future;
  4. use actix::prelude::*;
  5. struct MyActor {
  6. count: usize,
  7. }
  8. impl Actor for MyActor {
  9. type Context = Context<Self>;
  10. }
  11. struct Ping(usize);
  12. impl Message for Ping {
  13. type Result = usize;
  14. }
  15. impl Handler<Ping> for MyActor {
  16. type Result = usize;
  17. fn handle(&mut self, msg: Ping, ctx: &mut Context<Self>) -> Self::Result {
  18. self.count += msg.0;
  19. self.count
  20. }
  21. }
  22. fn main() {
  23. let system = System::new("test");
  24. // start new actor
  25. let addr = MyActor{count: 10}.start();
  26. // send message and get future for result
  27. let res = addr.send(Ping(10));
  28. Arbiter::spawn(
  29. res.map(|res| {
  30. # System::current().stop();
  31. println!("RESULT: {}", res == 20);
  32. })
  33. .map_err(|_| ()));
  34. system.run();
  35. }

Ping示例位于示例中。