Gateway

การฝัง OpenClaw

โฮสต์ที่ฝังระบบควรกำกับดูแลไฟล์ปฏิบัติการ openclaw ที่ติดตั้งไว้ ใช้โปรโตคอล WebSocket ของ Gateway เป็นระนาบควบคุม และถือว่าโปรเซสลูกเป็นรันไทม์ที่เปลี่ยนทดแทนได้ วิธีนี้ทำให้ความเป็นเจ้าของโปรเซส ความพร้อมใช้งาน การกู้คืนจากความล้มเหลว และการอัปเกรดมีความชัดเจน โดยไม่ต้องพึ่งพาโครงสร้างสถานะภายในของ OpenClaw

สำหรับการตรวจสอบสิทธิ์ไคลเอนต์และสถานะการเชื่อมต่อใหม่ โปรดอ่าน การสร้างไคลเอนต์ Gateway

เริ่มโปรเซสลูกด้วยค่าที่ตั้งไว้ล่วงหน้าสำหรับการฝังระบบ

ใช้การติดตั้ง node_modules จริงและเรียกไฟล์ปฏิบัติการของแพ็กเกจ ค่าพื้นฐานที่เหมาะสมสำหรับโฮสต์ซึ่งเป็นเจ้าของการค้นหา การเริ่มใหม่ และวงจรชีวิตของช่องทางคือ:

ts
import { spawn } from "node:child_process";import { dirname, resolve } from "node:path";import { fileURLToPath } from "node:url"; // ระบุพาธสัมบูรณ์ไปยังรันไทม์ 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 ที่มนุษย์อ่านได้:

  1. เรียกใช้ openclaw doctor --fix --yes --non-interactive กับสภาพแวดล้อมการกำหนดค่าและสถานะเดียวกับโปรเซสลูก Gateway
  2. ลองเริ่ม Gateway ใหม่หนึ่งครั้งหลังจาก doctor จบการทำงานสำเร็จ
  3. หากโปรเซสลูกออกด้วย 78 อีกครั้ง ให้หยุดลูปการซ่อมแซมและแจ้งความล้มเหลวของการกำหนดค่าแก่ผู้ใช้

เก็บ stderr ไว้สำหรับการวินิจฉัย แต่อย่าตัดสินใจเกี่ยวกับวงจรชีวิตจากข้อความในนั้น

หลังจากเริ่มต้นสำเร็จ การแก้ไขการกำหนดค่าแบบสดให้ไม่ถูกต้องจะสร้างความเสียหายน้อยกว่า ตัวเฝ้าดูการกำหนดค่าจะบันทึกว่าได้ข้ามการโหลดใหม่ และให้บริการต่อด้วยการกำหนดค่าในหน่วยความจำชุดล่าสุดที่ยอมรับ ซ่อมแซมไฟล์ แล้วปล่อยให้ตัวเฝ้าดูยอมรับสแนปช็อตที่ถูกต้องชุดถัดไป

รอความพร้อมของโปรโตคอล

ใช้สัญญาณ WebSocket แทนการค้นหาข้อความย่อยในบันทึก:

  1. เปิด WebSocket ของ Gateway
  2. รอเหตุการณ์ connect.challenge ซึ่งยืนยันว่าตัวรับฟังยอมรับ WebSocket แล้วและสามารถเริ่มแฮนด์เชกแบบท้าทายได้
  3. ส่ง connect พร้อมลายเซ็นอุปกรณ์ที่ผูกกับคำท้าทาย
  4. ถือว่า 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 อย่าทำให้แพ็กเกจแบนราบลงในบันเดิลของแอป และอย่ารวมเฉพาะไฟล์ส่วนขยายบางไฟล์ไว้ในโปรเจกต์

เนื้อหาที่เกี่ยวข้อง

Was this useful?
ในหน้านี้

ในหน้านี้