کلاینت، کارگزار(Broker) و ایجاد ارتباط
بیایید اکنون به نقشهای کلاینت و کارگزار MQTT و پارامترها و گزینههایی که هنگام اتصال به یک کارگزار در دسترس هستند، عمیق تر بپردازیم:
کلاینت
کلاینتهای MQTT هم ناشر(Publisher) و هم مشترک(Subscriber) هستند. برچسبهای ناشر و مشترک به این موضوع اشاره میکنند که آیا مشتری در حال انتشار پیامها یا اشتراک پیامها است (عملکرد انتشار و اشتراک نیز میتواند در همان کلاینت MQTT پیادهسازی شود). کلاینت MQTT هر دستگاهی است (از یک میکروکنترلر تا یک سرور کامل) که یک کتابخانه MQTT را اجرا می کند و از طریق شبکه به یک کارگزار MQTT متصل می شود.
برای مثال، کلاینت MQTT میتواند یک دستگاه بسیار کوچک و با محدودیت منابع باشد که از طریق یک شبکه بیسیم متصل میشود و دارای حداقلهای کتابخانه است. کلاینت MQTT همچنین می تواند یک کامپیوتر معمولی باشد که یک کلاینت گرافیکی MQTT را برای اهداف آزمایشی اجرا میکند. اساساً، هر دستگاهی که MQTT که از TCP/IP پشتیبانی میکند، می تواند کلاینت MQTT نامیده شود. اجرای پروتکل MQTT کلاینت بسیار ساده است. سهولت اجرا یکی از دلایلی است که MQTT برای دستگاه های کوچک مناسب است. کتابخانه های سرویس گیرنده MQTT برای انواع زیادی از زبانهای برنامه نویسی در دسترس هستند. به عنوان مثال، Android، Arduino، C، C++، C#، Go، iOS، Java، JavaScript و .NET. کتابخانه MQTT ویرالینک هم در زبانهای مختلف از کتابخانههای رسمی MQTT هر زبان استفاده میکند.
کارگزار
همتای کلاینت MQTT کارگزار MQTT است. کارگزار در قلب هر پروتکل انتشار/اشتراک قرار دارد. بسته به پیاده سازی، یک کارگزار می تواند تا هزاران کلاینت MQTT متصل به طور همزمان را مدیریت کند.
کارگزار مسئول دریافت همه پیامها، فیلتر کردن پیامها، تعیین مشترکین هر پیام و ارسال پیام به این کلاینت مشترک است. همچنین جلسات(session) تمام کلاینتهای مستمر، از جمله اشتراکها و پیامهای از دست رفته را نگه میدارد. یکی دیگر از وظایف کارگزار، احراز هویت و مجوز دادن به کلاینتهاست. معمولاً کارگزار قابل توسعه است که احراز هویت سفارشی، مجوز و ادغام در سیستم های سمت سرور (Back-end) را تسهیل میکند. یکپارچهسازی از اهمیت ویژهای برخوردار است زیرا کارگزار غالباً مؤلفهای است که مستقیماً در اینترنت در معرض دید قرار میگیرد، مشتریان زیادی را مدیریت میکند و باید پیامها را به سیستمهای تحلیل و پردازش پاییندستی ارسال کند. به طور خلاصه، کارگزار هاب مرکزی است که هر پیامی باید از آن عبور کند. بنابراین، مهم است که کارگزار شما بسیار مقیاس پذیر، قابل ادغام در سیستمهای سمت سرور، نظارت آسان و البته مقاوم در برابر شکست باشد.
اتصال MQTT
پروتکل MQTT مبتنی بر TCP/IP است. هم کلاینت و هم کارگزار باید یک پشته TCP/IP داشته باشند.
اتصال MQTT همیشه بین یک کلاینت و کارگزار است. کلاینتها هرگز مستقیماً به یکدیگر متصل نمیشوند.
برای شروع یک اتصال، کلاینت یک پیام CONNECT را به کارگزار ارسال می کند. کارگزار با CONNACK پاسخ میدهد
پیام و کد وضعیت هنگامی که اتصال برقرار شد، کارگزار آن را باز نگه می دارد تا زمانی که کلاینت دستور قطع اتصال را ارسال کند یا اتصال قطع شود.
اتصال MQTT از طریق NAT
در بسیاری از موارد استفاده رایج، کلاینت MQTT در پشت روتر یا مودمی قرار دارد که از ترجمه آدرس شبکه (NAT) برای ترجمه از آدرس شبکه خصوصی (مانند 192.168.0.0 و 10.0.0.0) به آدرس عمومی استفاده میکند. کلاینت MQTT اتصال را با ارسال یک پیام CONNECT به کارگزار آغاز میکند. از آنجایی که کارگزار یک آدرس عمومی دارد و اتصال را باز نگه می دارد تا امکان ارسال و دریافت دوطرفه پیامها را فراهم کند (پس از اتصال اولیه)، هیچ مشکلی با کلاینتهایی که در پشت NAT قرار دارند وجود ندارد.
CONNECT Message – Client Initiates Connection
برای شروع یک اتصال، کلاینت یک پیام فرمان به کارگزار ارسال میکند. اگر این پیام CONNECT بد شکل باشد (طبق مشخصات MQTT) یا زمان زیادی بین باز کردن سوکت شبکه و ارسال پیام اتصال بگذرد، کارگزار اتصال را میبندد. این رفتار از کلاینتهای مخربی را که میتوانند کارگزار را کند کنند، جلوگیری میکند. یک کلاینت درست یک پیام اتصال با محتوای زیر ارسال می کند (از جمله موارد دیگر)

برخی از اطلاعات موجود در پیام CONNECT احتمالاً برای کتابخانه نویسان MQTT بیشتر از سایرین جالبتر است. برای تمام جزئیات، نگاهی به مشخصات MQTT 3.1.1 بیندازید.
ما بر روی گزینه های زیر تمرکز خواهیم کرد:
ClientId: شناسه کلاینت (ClientId) هر کلاینت MQTT را که به یک کارگزار MQTT متصل میشود، مشخص میکند. کارگزار از ClientID برای شناسایی کلاینت و وضعیت فعلی کلاینت استفاده میکند. بنابراین، این شناسه باید برای هر کلاینت و کارگزار منحصر به فرد باشد. در MQTT 3.1.1 (استاندارد فعلی)، اگر نیازی به یک وضعیت ندارید که توسط کارگزار نگهداری شود، می توانید یک ClientId خالی ارسال کنید. ClientID خالی منجر به اتصال بدون هیچ حالتی میشود. در این حالت، Clean Session flag باید روی true تنظیم شود وگرنه کارگزار اتصال را رد میکند.
Clean Session: پرچم جلسه تمیز به کارگزار میگوید که آیا کلاینت میخواهد یک جلسه دائمی ایجاد کند یا خیر. در یک جلسه دائمی (CleanSession = false)، کارگزار تمام اشتراکها را برای کلاینت و همه پیامهای از دست رفته را برای کلاینتی که با کیفیت خدمات (QoS) سطح 1 یا 2 مشترک شده است ذخیره میکند.
اگر جلسه دائمی نباشد (CleanSession = درست)، کارگزار چیزی را برای کلاینت ذخیره نمیکند و تمام اطلاعات جلسه دائمی قبلی را پاک می کند.
نام کاربری/رمز عبور: MQTT می تواند نام کاربری و رمز عبور را برای احراز هویت و مجوز کلاینت ارسال کند. با این حال، اگر این اطلاعات رمزگذاری یا هش نشده باشد (از طریق پیاده سازی یا TLS)، رمز عبور به صورت متن ساده ارسال میشود. استفاده از نام کاربری و رمز عبور همراه با ارسال ایمن را به شدت توصیه می کنیم. کارگزار ویرالینک می تواند کلاینتها را با گواهی SSL احراز هویت کند، بنابراین نیازی به نام کاربری و رمز عبور نیست. (X.509)
Will Message: آخرین will message بخشی از ویژگی Last Will and Testament (LWT) از MQTT است. این پیام زمانی که یک کلاینت به طور نامطلوب قطع میشود به کلاینتهای دیگر اطلاع میدهد. هنگامی که کلاینت متصل میشود، می تواند آخرین will message را در قالب یک پیام MQTT و موضوع در پیام CONNECT به کارگزار ارائه دهد. اگر کلاینت به طور ناگهانب قطع شود، کارگزار پیام LWT را از طرف کلاینت ارسال میکند.
KeepAlive: مقدار Keep alive یک بازه زمانی بر حسب ثانیه است که کلاینت هنگام برقراری ارتباط با کارگزار مشخص میکند. این بازه طولانیترین مدت زمانی را که کارگزار و کلاینت میتوانند بدون ارسال پیام تحمل کنند را مشخص میکند. کلاینت متعهد میشود که پیامهای درخواست PING معمولی را برای کارگزار ارسال کند. کارگزار با یک پاسخ PING پاسخ میدهد. این روش به هر دو طرف اجازه می دهد تا تعیین کنند که آیا دیگری هنوز در دسترس است یا خیر.
اساساً، این تمام اطلاعاتی است که برای اتصال به یک کارگزار MQTT از یک کلاینت MQTT نیاز دارید. کتابخانه های فردی اغلب دارای گزینه های اضافی هستند که می توانید آنها را پیکربندی کنید.
پیام CONNACK – پاسخ کارگزار
هنگامی که یک کارگزار پیام CONNECT را دریافت می کند، موظف است با یک پیام CONNACK پاسخ دهد.
پیام CONNACK شامل دو ورودی داده است:
• پرچم حاضر جلسه
• پرچم تایید اتصال
پرچم حاضر جلسه (session present flag):
پرچم حاضر جلسه به مشتری می گوید که آیا کارگزار قبلاً یک جلسه دائمی در دسترس از تعاملات قبلی با مشتری دارد یا خیر.
هنگامی که یک کلاینت با Clean Session روی true متصل می شود، پرچم فعلی جلسه همیشه نادرست است زیرا هیچ جلسه ای در دسترس نیست. اگر یک کلاینت با Clean Session بر روی false وصل شود، دو احتمال وجود دارد: اگر اطلاعات جلسه برای شناسه کلاینت در دسترس باشد و کارگزار اطلاعات جلسه را ذخیره کرده باشد، پرچم فعلی جلسه درست است. در غیر این صورت، اگر کارگزار هیچ اطلاعات جلسه ای برای شناسه کلاینت نداشته باشد، پرچم فعلی جلسه نادرست است. این برای کمک به کلاینتها برای تعیین اینکه آیا آنها نیاز به اشتراک در موضوعات دارند یا اینکه آیا موضوعات هنوز در یک جلسه دائمی ذخیره میشوند، انجام میشود.
پرچم تأیید اتصال (connect acknowledge flag):
پرچم دوم در پیام CONNACK، پرچم تایید اتصال است. این پرچم حاوی یک کد بازگشتی است که به مشتری می گوید آیا تلاش برای اتصال موفقیت آمیز بوده است یا خیر.

در یک نگاه، کدهای بازگشت را مشاهده می کنید:

منبع : کتاب MQTT Essentials E-Book – HIVEMQ