กรอบนักแสดงสำหรับสนิม
Any ) หากต้องการใช้ actix ให้เพิ่มสิ่งนี้ลงใน Cargo.toml ของคุณ:
[ dependencies ]
actix = " 0.13 " ในการใช้ Actix คุณต้องสร้าง System ก่อน
fn main ( ) {
let system = actix :: System :: new ( ) ;
system . run ( ) ;
} Actix ใช้ Tokio Runtime System::new() สร้างลูปเหตุการณ์ใหม่ System.run() เริ่มต้นลูปเหตุการณ์ TOKIO และจะเสร็จสิ้นเมื่อนักแสดง System ได้รับข้อความ SystemExit
ในการกำหนดนักแสดงคุณต้องกำหนดโครงสร้างและให้มันใช้คุณสมบัติของ Actor
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 ( ) ;
} การวางไข่นักแสดงใหม่ทำได้ผ่านการ start และ create วิธีการของนักแสดง มันมีวิธีการสร้างนักแสดงที่แตกต่างกันหลายวิธี สำหรับรายละเอียดตรวจสอบเอกสาร คุณสามารถใช้วิธี started stopping และ stopped วิธีการของนักแสดง started ได้รับการเรียกเมื่อนักแสดงเริ่มต้นและ stopping เมื่อนักแสดงจบ ตรวจสอบเอกสาร API สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวงจรชีวิตของนักแสดง
นักแสดงสื่อสารกับนักแสดงคนอื่นโดยการส่งข้อความ ใน Actix ข้อความทั้งหมดจะถูกพิมพ์ เรามากำหนดข้อความ Sum อย่างง่ายด้วยพารามิเตอร์ usize สองพารามิเตอร์และนักแสดงที่จะยอมรับข้อความนี้และส่งคืนผลรวมของตัวเลขสองตัวนั้น ที่นี่เราใช้แอตทริบิวต์ #[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 คุณสามารถ do_send ข้อความโดยไม่ต้องรอการตอบกลับหรือคุณสามารถ send ข้อความเฉพาะนักแสดง ลักษณะ 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 ( ) ;
}ดูตัวอย่างการแชทนี้ซึ่งแสดงการใช้งานที่ครอบคลุมมากขึ้นในบริการไคลเอนต์/เซิร์ฟเวอร์เครือข่าย
ยินดีต้อนรับการมีส่วนร่วมทั้งหมดหากคุณมีคำขอคุณสมบัติอย่าลังเลที่จะเปิดปัญหา!
โครงการนี้ได้รับใบอนุญาตภายใต้ทั้งสองอย่าง
ตามตัวเลือกของคุณ
การมีส่วนร่วมใน Actix repo จัดขึ้นภายใต้เงื่อนไขของพันธสัญญาผู้สนับสนุน ทีม Actix สัญญาว่าจะแทรกแซงเพื่อรักษาจรรยาบรรณนั้น