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

واقعاً چه چیزی از NAT عبور می‌کند

وقتی دستگاه یک اتصال TCP به بروکر باز می‌کند، روتر خانه یک نگاشت می‌سازد و آن را در طول عمر جریان زنده نگه می‌دارد. پاسخ‌های روی همان جریان به دستگاه برمی‌گردند چون نگاشت از قبل وجود دارد. بروکر هرگز چیزی به سمت خانه آغاز نمی‌کند، پس بستهٔ ورودی ناخواسته‌ای نیست که روتر رد کند. تمام استدلال شبکه همین است و به همین دلیل این رویکرد در شبکه‌هایی کار می‌کند که کنترلشان نمی‌کنید.

دستگاه باید اتصال را زنده نگه دارد یا دوباره برقرار کند، و این پس از تثبیت معماری به پرسش قابلیت اطمینان تبدیل می‌شود.

بروکر موضوع‌ها را مسیریابی می‌کند، HTTP را پروکسی نمی‌کند

MQTT تبادل‌های انتشار و اشتراک را تعریف می‌کند: دستگاه در فیلتر موضوعی مشترک می‌شود که اجازهٔ خواندنش را دارد و یک کنترل‌کنندهٔ مجاز در موضوعی مطابق منتشر می‌کند. بروکر انتشارها را با اشتراک‌ها تطبیق می‌دهد و رونوشت‌ها را تحویل می‌دهد. نمی‌داند درخواست مرورگر چیست و یک HTTP GET را به وب‌سرور دستگاه ارسال نمی‌کند. اگر سفت‌افزار موجود فقط HTTP صحبت کند، طراحی بروکر به تغییری در برنامه یا یک مؤلفهٔ ترجمهٔ عامدانه نیاز دارد.

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

منابع دستگاه شکل TLS را تعیین می‌کند

ESP8266 حافظهٔ RAM محدودی دارد و دست‌دادن TLS گران‌ترین کاری است که انجام می‌دهد. هستهٔ Arduino دقیقاً برای همین محدودیت BearSSL را عرضه می‌کند و انتخاب میان بررسی یک CA و سنجاق‌کردن یک اثر انگشت هم ردپای حافظه را تغییر می‌دهد و هم آنچه مهاجمی با گواهی معتبر برای نامی دیگر می‌تواند بکند. بررسی CA بروکر گزینهٔ قوی‌تری است وقتی هیپ اجازه می‌دهد. اندازهٔ بار مفید هم مهم است: کلاینت MQTT یک بافر نگه می‌دارد و پیام‌های بزرگ‌تر از آن بی‌صدا بریده می‌شوند مگر اینکه بافر عامدانه بزرگ‌تر شود.

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

معناشناسی پیامی که گاز می‌گیرد

پیام نگه‌داشته‌شده را بروکر ذخیره می‌کند و به مشترکان مطابق بعدی تحویل می‌دهد، که برای وضعیت کنونی عالی و برای فرمان‌های یک‌باره خطرناک است: دستگاهی که دوباره وصل می‌شود می‌تواند فرمان دیروز را چنان دریافت کند که گویی تازه است. QoS 1 تحویل دست‌کم یک‌بار را تضمین می‌کند، پس تکرارها عادی‌اند و برنامه باید در برابر تکرار ایمن باشد، ترجیحاً با شناسه یا برچسب زمانی که بتواند ردش کند. وصیت آخرین وقتی دستگاه می‌افتد به شما سیگنال وضعیت می‌دهد، اما فقط اگر اتصال واقعاً شکست بخورد نه اینکه آویزان بماند.

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

TLS بخش تا بروکر را محافظت می‌کند. این رمزنگاری سرتاسری بار مفید در برابر گردانندهٔ بروکر نیست، که می‌تواند هر چیزی را که از طریق آن منتشر می‌کنید بخواند.

چرخهٔ عمر را محدود کنید و آن را با داده‌های بی‌خطر بیازمایید

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

با این کار، طراحی یک نیازمندی شبکهٔ ورودی را حذف می‌کند و نرم‌افزار دستگاه، سیاست بروکر و معناشناسی پیام را به‌عنوان کار آشکار باقی می‌گذارد نه فرض‌های پنهان.

مقالات مرتبط