Gateway
پروتکل پل
چرا وجود داشت
- مرز امنیتی: بهجای تمام سطح API مربوط به Gateway، فهرست مجاز کوچکی را در معرض دسترسی قرار میداد.
- جفتسازی + هویت Node: پذیرش Node تحت مالکیت Gateway بود و به توکن اختصاصی هر Node گره میخورد.
- تجربهٔ کاربری کشف: Nodeها میتوانستند Gatewayها را از طریق Bonjour در شبکهٔ محلی کشف کنند یا مستقیماً از طریق یک tailnet متصل شوند.
- WS در local loopback: صفحهٔ کنترل کامل WS محلی باقی میماند، مگر آنکه از طریق SSH تونلسازی میشد.
انتقال
- TCP، یک شیء JSON در هر خط (JSONL).
- TLS اختیاری (
bridge.tls.enabled: true). - پورت پیشفرض شنونده
18790بود.
وقتی TLS فعال بود، رکوردهای TXT کشف شامل bridgeTls=1 بههمراه bridgeTlsSha256 بهعنوان یک نشانهٔ غیرمحرمانه بودند. رکوردهای TXT مربوط به Bonjour/mDNS احراز اصالت نمیشوند؛ کلاینتها نمیتوانستند بدون تأیید خارج از باند دیگری، اثر انگشت اعلامشده را بهعنوان پین معتبر و قطعی در نظر بگیرند.
دستدهی و جفتسازی
- کلاینت پیام
helloرا همراه با فرادادهٔ Node و توکن (اگر از قبل جفت شده باشد) ارسال میکند. - اگر جفت نشده باشد، Gateway پاسخ
error(NOT_PAIRED/UNAUTHORIZED) را برمیگرداند. - کلاینت
pair-requestرا ارسال میکند. - Gateway منتظر تأیید میماند، سپس
pair-okوhello-okرا ارسال میکند.
hello-ok در گذشته serverName را برمیگرداند؛ اکنون سطوح Plugin میزبانیشده از طریق pluginSurfaceUrls در پروتکل فعلی Gateway اعلام میشوند (Canvas/A2UI از pluginSurfaceUrls.canvas استفاده میکند).
فریمها
از کلاینت به Gateway:
req/res: RPC محدودشدهٔ Gateway (گفتوگو، نشستها، پیکربندی، سلامت، voicewake، skills.bins).event: سیگنالهای Node (رونوشت صوتی، درخواست عامل، اشتراک گفتوگو، چرخهٔ حیات اجرا).
از Gateway به کلاینت:
invoke/invoke-res: فرمانهای Node (canvas.*،camera.*،screen.record،location.get،sms.send).event: بهروزرسانیهای گفتوگو برای نشستهای مشترکشده.ping/pong: زندهنگهداشتن اتصال.
اعمال فهرست مجاز در src/gateway/server-bridge.ts قرار داشت (حذف شده است).
رویدادهای چرخهٔ حیات اجرا
Nodeها برای نمایش فعالیت تکمیلشدهٔ system.run، رویداد exec.finished را منتشر میکردند که Gateway آن را به رویدادهای سیستمی نگاشت میکرد (Nodeهای قدیمی همچنین میتوانستند exec.started را منتشر کنند). exec.denied تلاش ردشدهٔ system.run را بهعنوان رد نهایی علامتگذاری میکرد، بدون آنکه رویداد سیستمی را در صف قرار دهد یا کار عامل را بیدار کند.
فیلدهای بار داده (همه اختیاری هستند، مگر آنکه خلافش ذکر شده باشد):
| فیلد | توضیحات |
|---|---|
sessionKey |
الزامی. نشست عامل برای همبستگی رویداد و، در مورد exec.finished، تحویل رویداد سیستمی. |
runId |
شناسهٔ یکتای اجرا برای گروهبندی. |
command |
رشتهٔ خام یا قالببندیشدهٔ فرمان. |
exitCode, timedOut, output |
جزئیات تکمیل (فقط برای اجرای پایانیافته). |
reason |
دلیل رد (فقط برای اجرای ردشده). |
کاربرد تاریخی tailnet
- اتصال پل به یک IP در tailnet: مقدار
bridge.bind: "tailnet"در~/.openclaw/openclaw.json(فقط تاریخی؛bridge.*دیگر پیکربندی معتبری نیست). - کلاینتها از طریق نام MagicDNS یا IP در tailnet متصل میشدند.
- Bonjour از مرز شبکهها عبور نمیکند؛ در غیر این صورت DNS-SD گسترده یا میزبان/پورت دستی لازم بود.
نسخهبندی
پل بهطور ضمنی نسخهٔ ۱ بود و مذاکرهای دربارهٔ حداقل/حداکثر نسخه نداشت. کلاینتهای فعلی Node/اپراتور از پروتکل Gateway مبتنی بر WebSocket استفاده میکنند که محدودهٔ نسخهٔ پروتکل را مذاکره میکند.