إطار الممثل للصدأ
Any نوع) لاستخدام actix ، أضف هذا إلى Cargo.toml :
[ dependencies ]
actix = " 0.13 " من أجل استخدام Actix تحتاج أولاً إلى إنشاء System .
fn main ( ) {
let system = actix :: System :: new ( ) ;
system . run ( ) ;
} يستخدم Actix وقت تشغيل Tokio. 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 بالتدخل لدعم مدونة قواعد السلوك هذه.