فارسی

کاوشی عمیق در تورنادو، یک فریمورک وب پایتون و کتابخانه شبکه‌سازی ناهمزمان. یاد بگیرید چگونه با توضیحات دقیق، مثال‌ها و بهترین شیوه‌ها، برنامه‌های مقیاس‌پذیر و با کارایی بالا بسازید.

مستندات تورنادو: راهنمای جامع برای توسعه‌دهندگان در سراسر جهان

تورنادو یک فریمورک وب پایتون و کتابخانه شبکه‌سازی ناهمزمان است که در اصل در FriendFeed توسعه یافته است. این فریمورک به ویژه برای long-polling، وب‌سوکت‌ها و سایر برنامه‌هایی که نیاز به اتصال طولانی‌مدت به هر کاربر دارند، مناسب است. ورودی/خروجی شبکه غیرمسدودکننده آن، آن را بسیار مقیاس‌پذیر و گزینه‌ای قدرتمند برای ساخت برنامه‌های وب با کارایی بالا می‌کند. این راهنمای جامع شما را با مفاهیم اصلی تورنادو آشنا کرده و مثال‌های عملی برای شروع کار ارائه می‌دهد.

تورنادو چیست؟

در هسته خود، تورنادو یک فریمورک وب و کتابخانه شبکه‌سازی ناهمزمان است. برخلاف فریمورک‌های وب همزمان سنتی، تورنادو از معماری تک-نخی و مبتنی بر حلقه رویداد استفاده می‌کند. این بدان معناست که می‌تواند اتصالات همزمان زیادی را بدون نیاز به یک نخ برای هر اتصال مدیریت کند، که آن را کارآمدتر و مقیاس‌پذیرتر می‌سازد.

ویژگی‌های کلیدی تورنادو:

راه‌اندازی محیط تورنادو

قبل از شروع توسعه با تورنادو، باید محیط خود را راه‌اندازی کنید. در اینجا یک راهنمای گام به گام آورده شده است:

  1. نصب پایتون: مطمئن شوید که پایتون 3.6 یا بالاتر را نصب کرده‌اید. می‌توانید آن را از وب‌سایت رسمی پایتون (python.org) دانلود کنید.
  2. ایجاد یک محیط مجازی (توصیه می‌شود): از venv یا virtualenv برای ایجاد یک محیط ایزوله برای پروژه خود استفاده کنید:
    python3 -m venv myenv
    source myenv/bin/activate  # در لینوکس/macOS
    myenv\Scripts\activate  # در ویندوز
  3. نصب تورنادو: تورنادو را با استفاده از pip نصب کنید:
    pip install tornado

اولین برنامه تورنادو شما

بیایید یک برنامه ساده "Hello, World!" با تورنادو ایجاد کنیم. فایلی به نام app.py ایجاد کرده و کد زیر را به آن اضافه کنید:

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
 def get(self):
  self.write("Hello, World!")

def make_app():
 return tornado.web.Application([
  (r"/", MainHandler),
 ])

if __name__ == "__main__":
 app = make_app()
 app.listen(8888)
 tornado.ioloop.IOLoop.current().start()

اکنون، برنامه را از ترمینال خود اجرا کنید:

python app.py

مرورگر وب خود را باز کرده و به http://localhost:8888 بروید. باید پیام "Hello, World!" را ببینید.

توضیحات:

مدیریت‌کننده‌های درخواست و مسیریابی

مدیریت‌کننده‌های درخواست، اساس برنامه‌های وب تورنادو هستند. آنها نحوه رسیدگی به درخواست‌های HTTP ورودی را بر اساس URL تعریف می‌کنند. مسیریابی، URLها را به مدیریت‌کننده‌های درخواست خاص نگاشت می‌کند.

تعریف مدیریت‌کننده‌های درخواست:

برای ایجاد یک مدیریت‌کننده درخواست، از tornado.web.RequestHandler ارث‌بری کرده و متدهای HTTP مناسب (get، post، put، delete و غیره) را پیاده‌سازی کنید.

class MyHandler(tornado.web.RequestHandler):
 def get(self):
  self.write("This is a GET request.")

 def post(self):
  data = self.request.body.decode('utf-8')
  self.write(f"Received POST data: {data}")

مسیریابی:

مسیریابی هنگام ایجاد tornado.web.Application پیکربندی می‌شود. شما لیستی از تاپل‌ها را ارائه می‌دهید که هر تاپل شامل یک الگوی URL و مدیریت‌کننده درخواست مربوطه است.

app = tornado.web.Application([
 (r"/", MainHandler),
 (r"/myhandler", MyHandler),
])

الگوهای URL:

الگوهای URL عبارات منظم هستند. می‌توانید از گروه‌های عبارات منظم برای گرفتن بخش‌هایی از URL و ارسال آنها به عنوان آرگومان به متدهای مدیریت‌کننده درخواست استفاده کنید.

class UserHandler(tornado.web.RequestHandler):
 def get(self, user_id):
  self.write(f"User ID: {user_id}")

app = tornado.web.Application([
 (r"/user/([0-9]+)", UserHandler),
])

در این مثال، /user/([0-9]+) با URLهایی مانند /user/123 مطابقت دارد. بخش ([0-9]+) یک یا چند رقم را گرفته و آنها را به عنوان آرگومان user_id به متد get از UserHandler ارسال می‌کند.

قالب‌بندی (Templating)

تورنادو شامل یک موتور قالب‌بندی ساده و کارآمد است. قالب‌ها برای تولید پویای HTML استفاده می‌شوند و منطق نمایش را از منطق برنامه جدا می‌کنند.

ایجاد قالب‌ها:

قالب‌ها معمولاً در فایل‌های جداگانه (مثلاً index.html) ذخیره می‌شوند. در اینجا یک مثال ساده آورده شده است:

<!DOCTYPE html>
<html>
<head>
 <title>My Website</title>
</head>
<body>
 <h1>Welcome, {{ name }}!</h1>
 <p>Today is {{ today }}.</p>
</body>
</html>

{{ name }} و {{ today }} متغیرهای جایگزینی هستند که با مقادیر واقعی هنگام رندر شدن قالب جایگزین می‌شوند.

رندر کردن قالب‌ها:

برای رندر کردن یک قالب، از متد render() در مدیریت‌کننده درخواست خود استفاده کنید:

class TemplateHandler(tornado.web.RequestHandler):
 def get(self):
  name = "John Doe"
  today = "2023-10-27"
  self.render("index.html", name=name, today=today)

مطمئن شوید که تنظیم template_path در تنظیمات برنامه شما به درستی پیکربندی شده باشد. به طور پیش‌فرض، تورنادو به دنبال قالب‌ها در پوشه‌ای به نام templates در همان دایرکتوری فایل برنامه شما می‌گردد.

app = tornado.web.Application([
 (r"/template", TemplateHandler),
], template_path="templates")

سینتکس قالب:

قالب‌های تورنادو از ویژگی‌های مختلفی پشتیبانی می‌کنند، از جمله:

عملیات ناهمزمان

قدرت تورنادو در قابلیت‌های ناهمزمان آن نهفته است. عملیات ناهمزمان به برنامه شما اجازه می‌دهد تا ورودی/خروجی غیرمسدودکننده انجام دهد و کارایی و مقیاس‌پذیری را بهبود بخشد. این امر به ویژه برای کارهایی که شامل انتظار برای منابع خارجی مانند کوئری‌های پایگاه داده یا درخواست‌های شبکه است، مفید می‌باشد.

@tornado.gen.coroutine:

دکوراتور @tornado.gen.coroutine به شما اجازه می‌دهد تا کد ناهمزمان را با استفاده از کلمه کلیدی yield بنویسید. این کار باعث می‌شود کد ناهمزمان بیشتر شبیه به کد همزمان به نظر برسد و رفتار کند، که خوانایی و قابلیت نگهداری را بهبود می‌بخشد.

import tornado.gen
import tornado.httpclient

class AsyncHandler(tornado.web.RequestHandler):
 @tornado.gen.coroutine
 def get(self):
  http_client = tornado.httpclient.AsyncHTTPClient()
  response = yield http_client.fetch("http://example.com")
  self.write(response.body.decode('utf-8'))

در این مثال، http_client.fetch() یک عملیات ناهمزمان است که یک Future را برمی‌گرداند. کلمه کلیدی yield اجرای کوروتین را تا زمان حل شدن Future به حالت تعلیق در می‌آورد. پس از حل شدن Future، کوروتین از سر گرفته شده و بدنه پاسخ به کلاینت نوشته می‌شود.

tornado.concurrent.Future:

یک Future نتیجه یک عملیات ناهمزمان را نشان می‌دهد که ممکن است هنوز در دسترس نباشد. می‌توانید از اشیاء Future برای زنجیر کردن عملیات ناهمزمان به یکدیگر و مدیریت خطاها استفاده کنید.

tornado.ioloop.IOLoop:

IOLoop قلب موتور ناهمزمان تورنادو است. این حلقه توصیفگرهای فایل و سوکت‌ها را برای رویدادها نظارت کرده و آنها را به مدیریت‌کننده‌های مناسب ارسال می‌کند. معمولاً نیازی به تعامل مستقیم با IOLoop ندارید، اما درک نقش آن در مدیریت عملیات ناهمزمان مهم است.

وب‌سوکت‌ها (WebSockets)

تورنادو پشتیبانی بسیار خوبی از وب‌سوکت‌ها فراهم می‌کند که ارتباط بی‌درنگ بین سرور و کلاینت‌ها را امکان‌پذیر می‌سازد. وب‌سوکت‌ها برای برنامه‌هایی که نیاز به ارتباط دوطرفه و با تأخیر کم دارند، مانند برنامه‌های چت، بازی‌های آنلاین و داشبوردهای بی‌درنگ، ایده‌آل هستند.

ایجاد یک مدیریت‌کننده وب‌سوکت:

برای ایجاد یک مدیریت‌کننده وب‌سوکت، از tornado.websocket.WebSocketHandler ارث‌بری کرده و متدهای زیر را پیاده‌سازی کنید:

import tornado.websocket

class WebSocketHandler(tornado.websocket.WebSocketHandler):
 def open(self):
  print("WebSocket opened")

 def on_message(self, message):
  self.write_message(f"You sent: {message}")

 def on_close(self):
  print("WebSocket closed")

 def check_origin(self, origin):
  return True # فعال کردن اتصالات وب‌سوکت بین مبدأ

ادغام وب‌سوکت‌ها در برنامه شما:

مدیریت‌کننده وب‌سوکت را به پیکربندی مسیریابی برنامه خود اضافه کنید:

app = tornado.web.Application([
 (r"/ws", WebSocketHandler),
])

پیاده‌سازی سمت کلاینت:

در سمت کلاینت، می‌توانید از جاوا اسکریپت برای برقراری اتصال وب‌سوکت و ارسال/دریافت پیام‌ها استفاده کنید:

const websocket = new WebSocket("ws://localhost:8888/ws");

websocket.onopen = () => {
 console.log("WebSocket connection established");
 websocket.send("Hello from the client!");
};

websocket.onmessage = (event) => {
 console.log("Received message:", event.data);
};

websocket.onclose = () => {
 console.log("WebSocket connection closed");
};

احراز هویت و امنیت

امنیت یک جنبه حیاتی در توسعه برنامه‌های وب است. تورنادو چندین ویژگی برای کمک به شما در ایمن‌سازی برنامه‌هایتان فراهم می‌کند، از جمله احراز هویت، اعطای دسترسی و محافظت در برابر آسیب‌پذیری‌های رایج وب.

احراز هویت:

احراز هویت فرآیند تأیید هویت یک کاربر است. تورنادو پشتیبانی داخلی برای طرح‌های مختلف احراز هویت فراهم می‌کند، از جمله:

اعطای دسترسی (Authorization):

اعطای دسترسی فرآیند تعیین اینکه آیا یک کاربر اجازه دسترسی به یک منبع خاص را دارد یا خیر است. شما می‌توانید منطق اعطای دسترسی را در مدیریت‌کننده‌های درخواست خود برای محدود کردن دسترسی بر اساس نقش‌ها یا مجوزهای کاربر پیاده‌سازی کنید.

بهترین شیوه‌های امنیتی:

استقرار (Deployment)

استقرار یک برنامه تورنادو شامل چندین مرحله است، از جمله پیکربندی یک وب سرور، راه‌اندازی یک مدیر فرآیند و بهینه‌سازی عملکرد.

وب سرور:

می‌توانید تورنادو را پشت یک وب سرور مانند Nginx یا Apache مستقر کنید. وب سرور به عنوان یک پراکسی معکوس عمل کرده و درخواست‌های ورودی را به برنامه تورنادو ارسال می‌کند.

مدیر فرآیند:

یک مدیر فرآیند مانند Supervisor یا systemd می‌تواند برای مدیریت فرآیند تورنادو استفاده شود و اطمینان حاصل کند که در صورت خرابی به طور خودکار راه‌اندازی مجدد می‌شود.

بهینه‌سازی عملکرد:

بین‌المللی‌سازی (i18n) و محلی‌سازی (l10n)

هنگام ساخت برنامه‌ها برای مخاطبان جهانی، مهم است که بین‌المللی‌سازی (i18n) و محلی‌سازی (l10n) را در نظر بگیرید. i18n فرآیند طراحی یک برنامه به گونه‌ای است که بتوان آن را بدون تغییرات مهندسی با زبان‌ها و مناطق مختلف تطبیق داد. l10n فرآیند تطبیق یک برنامه بین‌المللی شده برای یک زبان یا منطقه خاص با افزودن اجزای محلی و ترجمه متن است.

تورنادو و i18n/l10n

تورنادو به خودی خود کتابخانه‌های داخلی i18n/l10n ندارد. با این حال، شما می‌توانید به راحتی کتابخانه‌های استاندارد پایتون مانند `gettext` یا فریمورک‌های پیچیده‌تری مانند Babel را برای مدیریت i18n/l10n در برنامه تورنادوی خود ادغام کنید.

مثال با استفاده از `gettext`:

1. **راه‌اندازی localeهای خود:** برای هر زبانی که می‌خواهید پشتیبانی کنید، دایرکتوری‌هایی حاوی کاتالوگ‌های پیام (معمولاً فایل‌های `.mo`) ایجاد کنید.

locales/
 en/LC_MESSAGES/messages.mo
 fr/LC_MESSAGES/messages.mo
 de/LC_MESSAGES/messages.mo

2. **استخراج رشته‌های قابل ترجمه:** از ابزاری مانند `xgettext` برای استخراج رشته‌های قابل ترجمه از کد پایتون خود به یک فایل `.po` (Portable Object) استفاده کنید. این فایل حاوی رشته‌های اصلی و جایگزین‌هایی برای ترجمه‌ها خواهد بود.

xgettext -d messages -o locales/messages.po your_tornado_app.py

3. **ترجمه رشته‌ها:** رشته‌ها را در فایل‌های `.po` برای هر زبان ترجمه کنید.

4. **کامپایل کردن ترجمه‌ها:** فایل‌های `.po` را به فایل‌های `.mo` (Machine Object) کامپایل کنید که توسط `gettext` در زمان اجرا استفاده می‌شوند.

msgfmt locales/fr/LC_MESSAGES/messages.po -o locales/fr/LC_MESSAGES/messages.mo

5. **ادغام در برنامه تورنادوی شما:**

import gettext
import locale
import os
import tornado.web

class BaseHandler(tornado.web.RequestHandler):
 def initialize(self):
  try:
  locale.setlocale(locale.LC_ALL, self.get_user_locale().code)
  except locale.Error:
  # مدیریت مواردی که locale توسط سیستم پشتیبانی نمی‌شود
  print(f"Locale {self.get_user_locale().code} not supported")

  translation = gettext.translation('messages', 'locales', languages=[self.get_user_locale().code])
  translation.install()
  self._ = translation.gettext

 def get_current_user_locale(self):
  # منطق برای تعیین locale کاربر (مثلاً از هدر Accept-Language، تنظیمات کاربر و غیره)
  # این یک مثال ساده است - شما به یک راه‌حل قوی‌تر نیاز خواهید داشت
  accept_language = self.request.headers.get('Accept-Language', 'en')
  return tornado.locale.get(accept_language.split(',')[0].split(';')[0])

class MainHandler(BaseHandler):
 def get(self):
  self.render("index.html", _=self._)

settings = {
 "template_path": os.path.join(os.path.dirname(__file__), "templates"),
}

app = tornado.web.Application([
 (r"/", MainHandler),
], **settings)

6. **اصلاح قالب‌های خود:** از تابع `_()` (که به `gettext.gettext` متصل است) برای علامت‌گذاری رشته‌ها برای ترجمه در قالب‌های خود استفاده کنید.

<h1>{{ _("Welcome to our website!") }}</h1>
<p>{{ _("This is a translated paragraph.") }}</p>

ملاحظات مهم برای مخاطبان جهانی:

مباحث پیشرفته

صفحات خطای سفارشی:

می‌توانید صفحات خطایی را که تورنادو هنگام بروز خطا نمایش می‌دهد، سفارشی کنید. این به شما امکان می‌دهد تجربه کاربرپسندتری ارائه دهید و اطلاعات اشکال‌زدایی را شامل شوید.

تنظیمات سفارشی:

می‌توانید تنظیمات سفارشی را در پیکربندی برنامه خود تعریف کرده و در مدیریت‌کننده‌های درخواست خود به آنها دسترسی داشته باشید. این برای ذخیره پارامترهای خاص برنامه، مانند رشته‌های اتصال پایگاه داده یا کلیدهای API، مفید است.

تست:

برنامه‌های تورنادوی خود را به طور کامل تست کنید تا اطمینان حاصل شود که به درستی و ایمن کار می‌کنند. از تست‌های واحد، تست‌های یکپارچه‌سازی و تست‌های سرتاسری برای پوشش دادن تمام جنبه‌های برنامه خود استفاده کنید.

نتیجه‌گیری

تورنادو یک فریمورک وب قدرتمند و همه‌کاره است که برای ساخت برنامه‌های وب مقیاس‌پذیر و با کارایی بالا بسیار مناسب است. معماری ناهمزمان آن، پشتیبانی از وب‌سوکت و API با کاربری آسان، آن را به گزینه‌ای محبوب برای توسعه‌دهندگان در سراسر جهان تبدیل کرده است. با دنبال کردن دستورالعمل‌ها و مثال‌های این راهنمای جامع، می‌توانید ساخت برنامه‌های تورنادوی خود را شروع کرده و از ویژگی‌های متعدد آن بهره‌مند شوید.

به یاد داشته باشید که برای به‌روزترین اطلاعات و بهترین شیوه‌ها، به مستندات رسمی تورنادو مراجعه کنید. کدنویسی خوشی داشته باشید!