Gateway
การฝัง OpenClaw
โฮสต์ที่ฝังระบบควรกำกับดูแลไฟล์ปฏิบัติการ openclaw ที่ติดตั้งไว้ ใช้โปรโตคอล WebSocket ของ Gateway เป็นระนาบควบคุม และถือว่าโปรเซสลูกเป็นรันไทม์ที่เปลี่ยนทดแทนได้ วิธีนี้ทำให้ความเป็นเจ้าของโปรเซส ความพร้อมใช้งาน การกู้คืนจากความล้มเหลว และการอัปเกรดมีความชัดเจน โดยไม่ต้องพึ่งพาโครงสร้างสถานะภายในของ OpenClaw
สำหรับการตรวจสอบสิทธิ์ไคลเอนต์และสถานะการเชื่อมต่อใหม่ โปรดอ่าน การสร้างไคลเอนต์ Gateway
เริ่มโปรเซสลูกด้วยค่าที่ตั้งไว้ล่วงหน้าสำหรับการฝังระบบ
ใช้การติดตั้ง node_modules จริงและเรียกไฟล์ปฏิบัติการของแพ็กเกจ ค่าพื้นฐานที่เหมาะสมสำหรับโฮสต์ซึ่งเป็นเจ้าของการค้นหา การเริ่มใหม่ และวงจรชีวิตของช่องทางคือ:
// ระบุพาธสัมบูรณ์ไปยังรันไทม์ Node จริงที่จัดการโดยแอปพลิเคชันโฮสต์declare const hostNodeExecutable: string; const packageEntry = fileURLToPath(import.meta.resolve("openclaw"));const openclawEntry = resolve(dirname(packageEntry), "..", "openclaw.mjs");const gateway = spawn(hostNodeExecutable, [openclawEntry, "gateway", "--allow-unconfigured"], { env: { ...process.env, OPENCLAW_DISABLE_BONJOUR: "1", OPENCLAW_EXEC_SHELL_SNAPSHOT: "0", OPENCLAW_NO_RESPAWN: "1", OPENCLAW_SKIP_CHANNELS: "1", }, stdio: ["ignore", "inherit", "inherit"],});ให้ระบุตำแหน่ง OpenClaw ผ่านแพ็กเกจที่ติดตั้งไว้ตามตัวอย่าง อย่าสันนิษฐานว่าไบนารี openclaw ภายในโปรเจกต์อยู่ใน PATH ของโปรเซสโฮสต์ ตัวอย่างนี้สืบทอดเอาต์พุตเพื่อป้องกันไม่ให้โปรเซสลูกติดค้างเพราะไปป์ stdout หรือ stderr เต็ม หากโฮสต์ดักจับสตรีมเหล่านั้นแทน ให้แนบตัวอ่านทันทีหลังเรียกโปรเซส
| การตั้งค่า | ผลต่อการฝังระบบ |
|---|---|
OPENCLAW_DISABLE_BONJOUR=1 |
ปิดการโฆษณามัลติแคสต์บน LAN ที่ Gateway เป็นผู้จัดการ เมื่อโฮสต์เป็นเจ้าของการค้นหา |
OPENCLAW_NO_RESPAWN=1 |
ในโปรเซสลูกแบบฝังระบบที่ไม่มีตัวจัดการ ป้องกันไม่ให้ OpenClaw ส่งต่อการเริ่มใหม่หลังอัปเดตไปยังโปรเซสลูกที่แยกตัวออกไป การเริ่มใหม่ตามปกติยังคงอยู่ในโปรเซส ทำให้โฮสต์ยังเป็นเจ้าของ PID ที่ติดตามอยู่ |
OPENCLAW_EXEC_SHELL_SNAPSHOT=0 |
ปิดการบันทึกสแนปช็อตจากล็อกอินเชลล์สำหรับคำสั่ง exec ของโฮสต์ |
OPENCLAW_SKIP_CHANNELS=1 |
ข้ามการเริ่มต้นและโหลดช่องทางใหม่ ตั้งค่านี้เฉพาะเมื่อแอปที่ฝังระบบต้องการ Gateway ที่ใช้เฉพาะระนาบควบคุมหรือ WebChat |
--allow-unconfigured ข้ามเฉพาะตัวป้องกันการเริ่มต้น gateway.mode=local เท่านั้น โดยจะไม่เขียนการกำหนดค่าหรือซ่อมแซมไฟล์ที่ไม่ถูกต้อง ให้ละเว้นเมื่อแอปที่ฝังระบบจัดเตรียมการกำหนดค่าภายในเครื่องตามปกติผ่านการเริ่มต้นใช้งาน CLI การกำหนดค่า หรือ RPC ของ Gateway
คำเตือนเกี่ยวกับสแนปช็อตเชลล์ของ Electron
การบันทึกสแนปช็อตเชลล์เรียกใช้ process.execPath -e <script> จากล็อกอินเชลล์ ในโปรเซส Node ปกติ process.execPath คือไฟล์ปฏิบัติการ Node แต่ภายใต้ Electron ค่านี้คือไบนารี Electron ซึ่งอาจตีความการเรียกดังกล่าวว่าเป็นการเปิดแอปพลิเคชันและแสดงป๊อปอัป "Unable to find Electron app" ให้ตั้งค่า OPENCLAW_EXEC_SHELL_SNAPSHOT=0 ในสภาพแวดล้อมของโปรเซสลูก Gateway ไม่ใช่เฉพาะในโปรเซสเรนเดอร์ ด้วยเหตุผลเดียวกัน hostNodeExecutable ต้องชี้ไปยังรันไทม์ Node จริง ไม่ใช่ process.execPath ของ Electron
จัดการการกำหนดค่าที่ไม่ถูกต้องด้วยรหัสออก
การเริ่มต้น Gateway ใช้รหัสออก 78 (EX_CONFIG) สำหรับความล้มเหลวในการเริ่มต้นประเภทการกำหนดค่า รวมถึงการกำหนดค่าที่ไม่ถูกต้อง ให้แยกเส้นทางตามรหัสออกแทนการวิเคราะห์ stderr ที่มนุษย์อ่านได้:
- เรียกใช้
openclaw doctor --fix --yes --non-interactiveกับสภาพแวดล้อมการกำหนดค่าและสถานะเดียวกับโปรเซสลูก Gateway - ลองเริ่ม Gateway ใหม่หนึ่งครั้งหลังจาก doctor จบการทำงานสำเร็จ
- หากโปรเซสลูกออกด้วย
78อีกครั้ง ให้หยุดลูปการซ่อมแซมและแจ้งความล้มเหลวของการกำหนดค่าแก่ผู้ใช้
เก็บ stderr ไว้สำหรับการวินิจฉัย แต่อย่าตัดสินใจเกี่ยวกับวงจรชีวิตจากข้อความในนั้น
หลังจากเริ่มต้นสำเร็จ การแก้ไขการกำหนดค่าแบบสดให้ไม่ถูกต้องจะสร้างความเสียหายน้อยกว่า ตัวเฝ้าดูการกำหนดค่าจะบันทึกว่าได้ข้ามการโหลดใหม่ และให้บริการต่อด้วยการกำหนดค่าในหน่วยความจำชุดล่าสุดที่ยอมรับ ซ่อมแซมไฟล์ แล้วปล่อยให้ตัวเฝ้าดูยอมรับสแนปช็อตที่ถูกต้องชุดถัดไป
รอความพร้อมของโปรโตคอล
ใช้สัญญาณ WebSocket แทนการค้นหาข้อความย่อยในบันทึก:
- เปิด WebSocket ของ Gateway
- รอเหตุการณ์
connect.challengeซึ่งยืนยันว่าตัวรับฟังยอมรับ WebSocket แล้วและสามารถเริ่มแฮนด์เชกแบบท้าทายได้ - ส่ง
connectพร้อมลายเซ็นอุปกรณ์ที่ผูกกับคำท้าทาย - ถือว่า
hello-okคือความพร้อมของแอปพลิเคชันสำหรับ RPC ที่ผ่านการตรวจสอบสิทธิ์
คำท้าทายถูกส่งมาก่อนการเริ่มต้นระบบเสร็จสมบูรณ์โดยเจตนา หากไซด์คาร์สำหรับการเริ่มต้นยังทำงานไม่เสร็จ connect จะส่งคืนข้อผิดพลาด UNAVAILABLE ที่ลองใหม่ได้ พร้อม details.reason: "startup-sidecars" และ retryAfterMs ที่มีขอบเขตจำกัด จากนั้นจึงปิดด้วยรหัส 1013 และเหตุผล gateway starting ให้ใช้ resolveGatewayStartupRetryAfterMs จาก @openclaw/gateway-protocol/startup-unavailable หรือนโยบายที่มีอยู่ในไคลเอนต์อ้างอิง แล้วเชื่อมต่อใหม่
ตีความการเริ่มใหม่และการปิดระบบ
ก่อนปิดอย่างเป็นระเบียบ Gateway จะกระจายเหตุการณ์ shutdown พร้อม reason และ restartExpectedMs ค่า restartExpectedMs ที่ไม่เป็น null หมายความว่าคาดว่าจะมีการเริ่มใหม่ภายในโปรเซสหรือภายใต้การกำกับดูแล ส่วน null หมายถึงการปิดระบบขั้นสุดท้าย
รหัสปิด WebSocket ที่ตามมาคือ 1012 สำหรับทั้งสองกรณี เหตุผลการปิดของไคลเอนต์ตามปกติก็คือ service restart ในทั้งสองกรณี ดังนั้นทั้งรหัสปิดและเหตุผลจึงไม่สามารถแยกการเริ่มใหม่ออกจากการปิดระบบได้ ให้เก็บเพย์โหลด shutdown ก่อนหน้าไว้เมื่อได้รับ และรวมข้อมูลนั้นกับเจตนาหยุดของโฮสต์เองและสถานะออกของโปรเซสลูก หากการเชื่อมต่อหายไปโดยไม่มีเหตุการณ์ ให้ใช้นโยบายการเชื่อมต่อใหม่แบบมีขอบเขตและการกำกับดูแลโปรเซสลูกตามปกติ
ใช้ RPC แทนไฟล์สถานะ
ให้ Gateway เป็นเจ้าของสถานะ OpenClaw เพียงรายเดียว การดำเนินการฝังระบบทั่วไปมีเมธอด RPC อยู่แล้ว:
| งาน | เมธอด RPC |
|---|---|
| แค็ตตาล็อกและวงจรชีวิตของเซสชัน | sessions.list, sessions.patch, sessions.delete |
| การแสดงทรานสคริปต์ | chat.history |
| รายงานต้นทุนและการใช้งาน | usage.cost, sessions.usage |
| สถานะข้อมูลประจำตัวของโมเดล | models.authStatus |
| การกำหนดค่า | config.get, config.patch |
config.get ปกปิดค่าที่ละเอียดอ่อนและตัวระบุ SecretRef ก่อนส่งคืนสแนปช็อต เมธอดสำหรับเขียนจะส่งคืนการกำหนดค่าที่ปกปิดแล้วเช่นกัน ไคลเอนต์ต้องถือว่าค่าเครื่องหมายปกปิดเป็นข้อมูลทึบและใช้สัญญาการเขียนการกำหนดค่าที่ระบุไว้ในเอกสาร โดยต้องไม่คาดหวังให้ Gateway ส่งคืนข้อมูลลับแบบข้อความธรรมดา
อย่าอ่านหรือแก้ไขไฟล์ ตาราง SQLite ไฟล์ทรานสคริปต์ หรือไดเรกทอรีแคชภายใต้ ~/.openclaw เพื่อใช้สร้างฟีเจอร์ของแอป โครงสร้างเหล่านั้นเป็นรายละเอียดการใช้งานภายในของรันไทม์ และอาจย้ายหรือเปลี่ยนแปลงได้โดยไม่ต้องรักษาความเข้ากันได้ของโปรโตคอล
ติดตั้ง อย่าทำให้โครงสร้างแบนราบ
แพ็กเกจราก openclaw ไม่ใช่เป้าหมายสำหรับการรวมโค้ดแบบไฟล์เดียว ไฟล์รันไทม์ที่รวมมาให้ภายใต้ dist/extensions ยังคงมีการนำเข้าตัวเองแบบ bare เช่น openclaw/plugin-sdk/* ขณะที่แพ็กเกจ npm จงใจไม่รวมโครงสร้าง node_modules ของแต่ละส่วนขยาย
ติดตั้ง OpenClaw ผ่าน npm, pnpm หรือการติดตั้งแพ็กเกจ Node ตามปกติแบบอื่น เพื่อให้ Node สามารถแก้ไข package exports และโครงสร้างการพึ่งพาระดับรากได้ เรียกไฟล์ปฏิบัติการ openclaw ที่ติดตั้งไว้ อย่าคัดลอกเฉพาะ dist อย่าทำให้แพ็กเกจแบนราบลงในบันเดิลของแอป และอย่ารวมเฉพาะไฟล์ส่วนขยายบางไฟล์ไว้ในโปรเจกต์