رفتن به محتوا

هدایت پورت از ترمینال

سروری که در ترمینال یک گفتگو راه می‌اندازید فقط برای همان فضا منتشر می‌شود. پنل پورت‌ها شنونده‌هایی را که این برنامه همان‌جا راه انداخته است می‌بیند، آن‌ها را نگاشت می‌کند و برای هر جایی که ممکن است بخواهید از آن‌جا به آن‌ها برسید نشانی‌ای می‌دهد. دو فضا می‌توانند هر دو روی 5173 گوش بدهند؛ نگاشت‌هایشان هرگز با هم قاطی نمی‌شوند.

هیچ‌چیز این‌جا ماشین را باز نمی‌کند: هر مسیر به‌درخواست سرور ساخته می‌شود و با ترمینال یا ریگ از بین می‌رود.

  1. ترمینال (VM) گفتگو یا پوستهٔ میزبان را باز کنید (در یک فضا یا در صفحهٔ یک PR).
  2. سرورتان را راه بیندازید — pnpm dev، python -m http.server 8000، هر چیزی.
  3. در عرض چند ثانیه آیکون دوشاخه در گوشهٔ بالا-راست ترمینال یک نقطه می‌گیرد. روی آن کلیک کنید.

پنل هر پورت در حال گوش‌دادن را همراه با فرایندی که مالکش است فهرست می‌کند، به شکل 3000 → 3000: در سمت چپ پورتی که فرایند روی آن بایند شده، و در سمت راست پورتی که به‌صورت محلی روی آن پاسخ می‌دهد (هرگاه روی ماشین شما آزاد بوده، همان عدد). هر ردیف همچنین می‌گوید آیا localhost رومیزی، مرورگر (VM) و Android می‌توانند به آن برسند.

کشف مهارشده است: ترمینال (VM) درون همان مهمان نظرسنجی می‌شود؛ پوستهٔ میزبان از درخت فرایندهای PTY همان نشست. فضاهای دیگر، و فرایندهای دیگر روی Mac شما، فهرست نمی‌شوند.

پورت‌های جدید در همین ترمینال به‌صورت خودکار فوروارد می‌شوند. اگر فقط پورت‌هایی را می‌خواهید که خودتان اضافه می‌کنید، فوروارد خودکار پورت‌ها را در همان پنل خاموش کنید.

از کپی URL محلی روی همان ردیف استفاده کنید — http://localhost:3000. فوروارد فقط روی لوپ‌بک گوش می‌دهد، پس هیچ چیز دیگری روی شبکه‌تان آن را نمی‌بیند.

اگر دو فضا هر دو 5173 مهمان را عرضه کنند و ماشین شما از قبل 127.0.0.1:5173 را در اختیار داشته باشد، فضای دوم 5173 مهمان را نگه می‌دارد و یک پورت محلی موقت می‌گیرد. کپی URL از عدد سمت راست استفاده می‌کند.

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

--host (یا بایند کردن 0.0.0.0) باعث نمی‌شود یک مرورگر محفظه‌ای (VM) بتواند به سروری روی Mac برسد. مهمان لوپ‌بک خودش را دارد؛ سرور وقتی زبانهٔ مرورگر در همان فضا باشد یک تونل را درون آن مهمان مستقر می‌کند.

مرورگر محفظه‌ای را در همان گفتگو باز کنید. localhost:<left-hand port> را تایپ کنید — همان عددی که فرایند روی آن بایند شده است. یک نگاشت مجدد (5173 → 3000) در آن مرورگر روی عدد سمت راست هم پاسخ می‌دهد، پس کپی URL آن‌جا هم کار می‌کند. browser_use یک عامل می‌تواند به هر یک از این دو برود. سروری در فضای A هرگز در مرورگر فضای B به شکل localhost:5173 ظاهر نمی‌شود.

از localhost استفاده کنید، نه یک IP LAN و نه --host. مهمان لوپ‌بک خودش را دارد؛ تونل آن‌جا روی هر دو IPv4 و IPv6 گوش می‌دهد.

صفحه‌هایی که هم‌زمان اتصال‌های زیادی باز می‌کنند (ده‌ها منبع، یک سوکت بارگذاری مجدد زنده) همان تونل را به اشتراک می‌گذارند. مرورگر (VM) آن‌ها را روی یک exec پایدار مالتی‌پلکس می‌کند، پس انفجاری از واکشی‌ها به‌ازای هر اتصال یک فرایند جدید نمی‌سازد و به شکل یک صفحهٔ سفید تایم‌اوت نمی‌شود.

درون یک فضا، فوروارد یک ترمینال (VM) بر یک پوستهٔ میزبان روی همان عدد برنده است. میان فضاها هیچ تقدمی وجود ندارد — آن‌ها نگاشت‌های جداگانه‌اند.

زبانهٔ Android همان فضا را باز کنید. آن‌گاه localhost:<port> شبیه‌ساز به پورت منتشرشدهٔ این فضا معکوس می‌شود (adb reverse). شبیه‌ساز در سطح دستگاه یکتاست: وصل کردن فضای B، :5173 را به B بازهدایت می‌کند و نسخهٔ A را می‌اندازد. زبانه را ببندید و معکوس‌هایی که این ریگ مستقر کرده بود حذف می‌شوند.

شبیه‌ساز iOS از قبل همان Mac است — بدون معکوس. یک iPhone فیزیکی هنوز به یک اشتراک LAN نیاز دارد.

⋯ → اشتراک در شبکهٔ محلی پورت را روی <server-ip>:<random port> منتشر می‌کند — برای باز کردن صفحه روی تلفنتان، یا وقتی سرور روی ماشین دیگری اجرا می‌شود، مفید است.

  • پورت LAN همیشه به دست OS تخصیص داده می‌شود، هرگز عدد مهمان نیست؛ پس افشا یک نشانی آگاهانه و دیدنی است، نه نشانی‌ای حدس‌زدنی.
  • تا وقتی روشنش نکنید خصوصی می‌ماند (فقط لوپ‌بک)، و ⋯ → فقط محلی آن را از شبکه بیرون می‌آورد.

⋯ → تنظیم دامنهٔ مرورگر (.test) به پورت یک دامنهٔ dev مانند myapp.test نسبت می‌دهد. آن‌گاه درون مرورگر (VM)، https://myapp.test سرور شما را با قفلی معتبر بارگذاری می‌کند — برای هر چیزی که روی یک مبدأ نام‌دار یا یک بافت امن رفتار متفاوتی دارد (کوکی‌ها، service workerها، بازگشت‌های OAuth) مفید است.

  • دامنه‌ها باید به .test یا .localhost ختم شوند — همان دو TLD رزروشده برای توسعه، تا یک نام dev هرگز نتواند روی یک سایت واقعی سایه بیندازد.
  • نامهای دامنه روی سرور یکتا هستند؛ شمارههای پورت یکتا نیستند. دو فضا می‌توانند هر دو از 5173 استفاده کنند، اما هر دو نمی‌توانند مدعی myapp.test شوند.
  • گواهی از یک مرجع گواهی محلی می‌آید که نخستین بار که لازم شود روی سرور شما صادر می‌شود. کلیدهایش زیر پوشهٔ دادهٔ سرور قرار دارند و هرگز وارد هیچ مهمانی نمی‌شوند؛ مرورگر محفظه‌ای دقیقاً همان یک کلید را معتبر می‌شمارد، پس TLS به اینترنت واقعی همچنان به‌طور عادی اعتبارسنجی می‌شود.
  • دامنه فقط درون مرورگر (VM) حل می‌شود. مرورگر خودتان روی میزبان به‌جایش از localhost:<port> استفاده می‌کند.
  • http://myapp.test ساده هم کار می‌کند.

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

پورت‌ها با فضای کاری و فضا کلید می‌خورند. نقشهٔ پورت خودِ هایپروایزر هنگام بوت شدن یک ماشین ثابت است، پس یک ترمینال (VM) روی دو کانال باریکِ تحت کنترل سرور سوار می‌شود: یک مسیر ورودی ازپیش‌ساخته به درون مهمان که از اتصال به هر پورتی که مهمان واقعاً روی آن گوش نمی‌دهد سر باز می‌زند، و تونل‌های معکوسی که سرور برای مرورگر (VM) و Android باز نگه می‌دارد. یک پوستهٔ میزبان هرگز کل ماشین را پویش نمی‌کند. هیچ شنونده‌ای هرگز درون مهمانی ساخته نمی‌شود که سرور آن را آن‌جا نگذاشته باشد، و همه‌چیز همراه با ترمینال یا ریگ برچیده می‌شود. طراحی در ریگ‌ها و محفظه‌ها توضیح داده شده است؛ پورت‌های رزروشدهٔ دقیق و قواعد دامنه در مرجع ریگ‌ها آمده‌اند.