برگزارکنندگان المپیک میخواهند سامانهای درست کنند که بهراحتی بتوانند اخبار برگزاری و وقایع هر رشته را به خبرگزاریهای مختلف ورزشی اطلاع دهند؛ به این صورت که یک سری پخشکنندهی اخبار دارند که وقایع را منتشر میکنند و یک سری دنبالکنندهی اخبار دارند که بهمحض دریافت خبر، آن را در خبرگزاریشان قرار میدهند. آنها از شما کمک خواستهاند تا در پیادهسازی این سامانه کمک کنید.
پیادهسازی
شما باید سه کلاس OlympicsServer
، Publisher
و Subscriber
را پیادهسازی کنید و همچنین توابع مشخصشدهی آنها را نیز پیادهسازی کنید. در صورت لزوم میتوانید توابع دیگری به کلاسهایتان اضافه کنید.
تعاریف
موضوع (topic)
هر خبری که منتشر میشود، یک موضوع دارد. بهطور مثال، sports/basketball/groupstage
یک موضوع است؛ یعنی این خبر یک خبر ورزشی در رشتهی بسکتبال و در دور گروهی مسابقات است.
پیام (message)
هر خبر یک پیام به همراه خود دارد. بهطور مثال، Football match result: Team A won!
پیامی است که منتشرکننده آن را انتشار میدهد. پیامها بهصورت یک رشته (string
) هستند.
کیفیت سرویس (QoS)
کیفیت سرویس یعنی خبری که منتشر میشود، برای منتشرکننده چه میزان اهمیت دارد که به دست دنبالکنندهاش برسد. بهطور مثال، کیفیت سرویس سطح صفر یعنی برای منتشرکننده هیچ اهمیتی ندارد که پیامش به دنبال کنندهاش رسیده یا نه؛ یعنی پس از انتشار آن را فراموش میکند. ولی کیفیت سرویس سطح یک یعنی برای منتشر کننده مهم است که حداقل پیامش به یک مخاطبش رسیده باشد و رسیدن پیام را حداقل به یک دنبالکننده گارانتی میکند.
منتشرکننده (publisher)
منتشرکننده یک کاربر (client) است که خبر را در یک موضوع مشخص، با یک پیام مشخص و یک کیفیت سرویس منتشر میکند. به طور مثال:
client.publish('sports/handball', 'Match result: Team A won!', qos=1)
دنبالکننده (subscriber)
دنبالکننده نیز یک کاربر است که یک موضوع مشخص را دنبال میکند و در صورت match شدن موضوعات، تابع callback
را صدا میزند. بهطور مثال:
client.subscribe('sports/football')
تابع callback
تابع callback
تابعی است که دنبالکننده پس از اینکه موضوع یک خبر با آن match میشود، آن تابع را صدا میزند. این تابع بهطور مثال میتواند پیام را چاپ کند یا در دیتابیس یا یک لیست اضافه کند. بهطور مثال این یک تابع callback
است که پیام را صرفاً چاپ میکند:
def message_callback(topic, message):
print(f"Received message on topic {topic}: {message}")
توجه داشته باشید که پیادهسازی این تابع را نیاز نیست انجام دهید و صرفا باید آن را هنگام match شدن تاپیک صدا بزنید.
سطوح دسترسی موضوعات
- دسترسی صفرسطحی: در این دسترسی دنبالکنندگان باید کاملاً با تاپیک منطبق باشند. (بهطور مثال
/sports
بهsports/football
دسترسی ندارد.) - دسترسی یکسطحی: در این دسترسی دنبالکنندگان تنها میتوانند در یک عمق با تاپیک اشتراک داشته باشند. (بهطور مثال
sports/+
بهsports/football
دسترسی دارد ولی بهsports/football/finals
دسترسی ندارد.) - دسترسی چندسطحی: در این دسترسی دنبالکنندگان در چند عمق میتوانند با تاپیک اشتراک داشته باشند. (بهطور مثال
sports/#
بهsports/football
دسترسی دارد و همچنین بهsports/football/finals
نیز دسترسی دارد.)
سرور
سرور به صورت چندنخی (multi-thread) کار میکند و هر خبر در یک نخ منتشر میشود. همچنین برای جلوگیری از race condition یک قفل (lock) در درون سرور قرار دارد که در جای لازم نخها را قفل میکند و همچنین دارای دو تابع اصلی publish
و subscribe
است. این دو تابع اکثر منطق برنامه را در خود جای میدهند و کلاس Publisher
و Subscriber
بهترتیب در خود publish
و subscribe
دارند که با استفاده از توابع متناظر خود در سرور عمل انتشار و دنبال کردن را انجام میدهند.
همچنین به این توجه داشته باشید که سرور باید برای دنبالکنندههایی که در حال حاضر آنلاین نیستند پیام را ذخیره کند. تاپیکها و پیامشان را به صورت آرایهای از تاپل و در فایل messages.pkl
و بهصورت فایل pickle
ذخیره کنید.
کاربر (client)
این کلاس برای شما پیادهسازی شده است که صرفاً در توابع publish
و subscribe
با ساختن یک کلاس متناظر با آن و صدا کردن تابعش عمل انتشار و دنبال کردن خبر را انجام میدهد.
مثال
کد نمونه
def message_callback(topic, message):
print(f"Received message on topic {topic}: {message}")
server = OlympicsServer()
client = Client(server)
client.subscribe('sports/#', message_callback)
client.publish('sports/football', 'Football match result: Team A won!', qos=1)
client.publish('sports/football/worldcup', 'World Cup result: Team Z won!', qos=1)
client.publish('sports/basketball/nba', 'NBA result: Team Y won!', qos=1)
خروجی نمونه
Received message on topic sports/football: Football match result: Team A won!
Received message on topic sports/football/worldcup: World Cup result: Team Z won!
Received message on topic sports/basketball/nba: NBA result: Team Y won!
در اینجا دنبالکننده چون موضوع sports/#
را دنبال کرده است، پس هر خبری که با sports
شروع شود را دریافت و با صدا زدن تابع callback
آن را چاپ میکند.
پروژهی اولیه
پروژهی اولیهی این سؤال را میتوانید از این لینک دانلود کنید.
نحوهی ارسال
پس از تکمیل پروژه، فایلهای client.py
و server.py
را به صورت یک فایل zip
را ارسال نمایید.
[your-zip-file-name].zip
├── client.py
└── server.py
ارسال پاسخ برای این سؤال