# Phát triển

> HTML: https://remote.ivjn.us/docs/vi/development/

Tài liệu này giải thích cách xây dựng, kiểm tra và chạy exchange cục bộ trong kho lưu trữ này. Các bước triển khai, bảng trường giao thức và chi tiết cài đặt nền tảng vẫn còn trong các tài liệu chuyên dụng được liên kết ở cuối.

## Chuỗi công cụ

Không gian làm việc sử dụng Rust 2021 và yêu cầu **Rust 1.88 hoặc mới hơn**. Phiên bản được ghi trong trường `rust-version` của `Cargo.toml` gốc.

## Không gian làm việc và nhị phân

Không gian làm việc Rust có chín thành viên: tám thành viên trong `crates/` và SDK mở rộng trong `sdk/extend/rust`. Các kiểu dữ liệu của giao thức chỉ được định nghĩa trong `crates/proto`; `exchange`, `agent` và `cli` cùng phụ thuộc vào crate này. Không định nghĩa lại cấu trúc thông điệp trong từng thành phần sử dụng.

| crate | Đường dẫn | đầu ra |
|---|---|---|
| `proto` | `crates/proto` | Thư viện; thông điệp điều khiển, khung nhị phân và cấu trúc dữ liệu dùng chung chỉ tồn tại ở đây |
| `exchange` | `crates/exchange` | `exchange` nhị phân (cùng gói và tên nhị phân) |
| `agent` | `crates/agent` | `remote-agent` nhị phân |
| `cli` | `crates/cli` | `remote-cli` nhị phân |
| `updater` | `crates/updater` | Thư viện tự cập nhật cho `remote-agent` và `remote-cli` |
| `telemetry` | `crates/telemetry` | Thư viện báo cáo nhật ký và ngoại lệ được chia sẻ cho cả ba thành phần |
| `tls-client` | `crates/tls-client` | Chính sách TLS của máy khách Rustls được chia sẻ và các kết nối proxy tùy chọn |
| `worker-proto` | `crates/worker-proto` | Xác thực giao thức và băm thông tin xác thực cho Workers Exchange |
| `remote-extend-sdk` | `sdk/extend/rust` | Thư viện; khung và hợp đồng của nhà cung cấp tiện ích mở rộng |

Điểm vào cho `exchange` là `crates/exchange/src/main.rs`, không có bảng `[[bin]]` riêng biệt, vì vậy `cargo build -p exchange` tạo ra `exchange`. Các tệp kê khai `agent` và `cli` (`Cargo.toml`) đặt tên rõ ràng cho các tệp nhị phân của chúng là `remote-agent` và `remote-cli`.

Các bảng kết nối được phân chia theo trách nhiệm:

- `crates/exchange/src/hub.rs` quản lý các thiết bị trực tuyến, thay thế kết nối lại và các kỷ nguyên.
- `crates/exchange/src/hub/session_table.rs` dịch ID phía nhà điều hành và phía thiết bị.
- `crates/exchange/src/hub/outbound.rs` quản lý hàng đợi gửi giới hạn cho mỗi kết nối.

## xây dựng

Chạy các lệnh này từ kho lưu trữ gốc.

Cấu hình phát hành (`opt-level = 2`, LTO mỏng, giữ lại thư giãn) xây dựng máy chủ, CLI và Agent:

```bash
cargo build --release
```

Các tệp nhị phân được đặt tại:

- `target/release/exchange`
- `target/release/remote-cli`
- `target/release/remote-agent`

`release` tiếp tục tháo gỡ vì exchange là một quá trình liên tục với nhiều kết nối. Nếu một tác vụ kết nối gặp trục trặc, việc giải nén sẽ cho phép tokio dừng tác vụ đó mà không cần gỡ bỏ các phiên của các thiết bị khác trong cùng một quy trình.

Thiết bị Agent cũng có cấu hình được tối ưu hóa kích thước (`opt-level = "z"`, LTO, `panic = "abort"`, `strip`, `codegen-units = 1`):

```bash
cargo build -p agent --no-default-features --profile release-small
```

Đầu ra là `target/release-small/remote-agent`. Vì Procd, systemd hoặc Trình lập lịch tác vụ khởi động lại Agent sau sự cố, cấu hình này có thể giao dịch `panic = "abort"` để lấy tệp nhị phân nhỏ hơn.

Cơ sở dữ liệu không cần thiết để biên dịch. `crates/exchange/src/db.rs` sử dụng truy vấn thời gian chạy sqlx thay vì macro `query!`, vì vậy `cargo build` hoạt động mà không cần cơ sở dữ liệu.

## Kiểm tra

```bash
cargo test --workspace
```

Windows bỏ qua các bài kiểm tra yêu cầu Unix `/bin/sh` (hoặc `/bin/ash` trên OpenWrt) và PTY. Mô-đun thử nghiệm trong `crates/agent/src/pty.rs` được bảo vệ bởi `#[cfg(all(test, unix))]` và không được biên dịch trên nền tảng không phải Unix. Việc triển khai PTY thử `/bin/ash` và sau đó là `/bin/sh`. Đường dẫn tín hiệu Unix và nhóm quy trình trong `exec.rs` cũng chỉ biên dịch trên Unix; Kiểm tra lệnh Windows sử dụng PowerShell mà không gọi `/bin/sh`. Sau khi thay đổi đường dẫn Unix trong `exec.rs` hoặc `pty.rs`, hãy chạy `cargo test --workspace` trên Linux; Chỉ riêng kết quả Windows là không đủ.

Thu hẹp phạm vi xuống một crate khi hữu ích, ví dụ `cargo test -p proto` hoặc `cargo test -p exchange -- hub::`.

## Chạy exchange cục bộ

Chuẩn bị PostgreSQL và đặt chuỗi kết nối của nó vào `DATABASE_URL`. Biến này ánh xạ tới tùy chọn `exchange` `--database-url` (xem `crates/exchange/src/config.rs`). Khi khởi động, `db::connect` chạy các di chuyển được nhúng vào thời gian biên dịch:

```rust
sqlx::migrate!("../../migrations")
```

Các tệp di chuyển nằm trong thư mục `migrations/` gốc của kho lưu trữ và chạy tự động khi khởi động; sqlx-cli là không cần thiết.

Các thao tác kiểm toán còn cần khóa mã hóa nhật ký kiểm toán. Ví dụ bên dưới tạo khóa thử nghiệm cục bộ. Hãy lưu khóa an toàn và dùng lại cùng khóa trong các lần khởi động sau; tạo khóa mới mỗi lần sẽ khiến không thể giải mã chi tiết kiểm toán đã lưu.

```bash
export DATABASE_URL='postgres://luci:luci@127.0.0.1:5432/luci'
export AUDIT_ENCRYPTION_KEY="$(python -c 'import base64, secrets; print(base64.b64encode(secrets.token_bytes(32)).decode())')"
cargo run -p exchange -- --listen 127.0.0.1:8080
```

Trong PowerShell, trước tiên hãy đặt biến môi trường:

```powershell
$env:DATABASE_URL = "postgres://luci:luci@127.0.0.1:5432/luci"
$env:AUDIT_ENCRYPTION_KEY = python -c "import base64, secrets; print(base64.b64encode(secrets.token_bytes(32)).decode())"
cargo run -p exchange -- --listen 127.0.0.1:8080
```

Nếu tệp nhị phân phát hành đã được tạo, hãy thay thế `cargo run -p exchange --` ở trên bằng `./target/release/exchange`. Địa chỉ nghe mặc định là `0.0.0.0:8080`; liên kết rõ ràng với `127.0.0.1` để gỡ lỗi cục bộ.

Khi cơ sở dữ liệu không có tài khoản nhà điều hành được kích hoạt, khởi động sẽ khởi động quản trị viên và chỉ in mã thông báo của nó trong nhật ký khởi động đó. Bản rõ xuất hiện một lần. Hướng dẫn triển khai, proxy ngược và tài khoản hoàn chỉnh có trong kho lưu trữ `docs/deployment.md`. Trang đó chứa địa chỉ máy chủ và không được xuất bản trên trang này.

## Kiểm tra trước khi cam kết

Chạy các kiểm tra này từ thư mục gốc của kho lưu trữ. Đối với các thay đổi của Rust, hãy bắt đầu bằng các thử nghiệm crate tập trung, sau đó hoàn tất kiểm tra không gian làm việc. Nếu kiểm tra định dạng tìm thấy sự trôi dạt hiện tại không liên quan, chỉ định dạng các tệp đã thay đổi thay vì định dạng lại mã khác. Android, tiện ích mở rộng trình duyệt và bảng điều khiển di động cũng cần các bản dựng và thử nghiệm riêng; Các thử nghiệm Rust không bao gồm các bề mặt đó.

```sh
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
```

## Duy trì tài liệu

Xác minh hành vi triển khai trước khi cập nhật hướng dẫn kho lưu trữ trong `docs/`. Các chủ đề của trang web có nguồn tham khảo tại `website/docs/<topic>.md` và chín bản dịch được tác giả tại `website/docs/content/<locale>/<topic>.md`. Giữ các lệnh, trường, ví dụ mã và cấp độ tiêu đề được căn chỉnh. Tạo các trang và chỉ mục tìm kiếm bằng tập lệnh thay vì chỉ chỉnh sửa HTML. Chạy phần sau từ thư mục gốc của kho lưu trữ với Python 3.11+, markdown-it-py và Node.js đã được cài đặt:

```sh
python -m pip install markdown-it-py
python scripts/build-docs.py
python scripts/build-docs.py --check
python scripts/test-docs.py
python scripts/test-docs-markdown.py
node scripts/test-docs-locale.js
python scripts/test-build-docs.py
python scripts/test-site-seo.py
```

Quá trình kiểm tra thế hệ cũng so sánh từng byte tệp được tạo ra, không ghi được đầu ra bị thiếu hoặc cũ mà không ghi tệp. CI chạy nó trước khi xây dựng lại.

Việc kiểm tra xác thực tính đầy đủ của bản dịch, ví dụ mã, cấu trúc tiêu đề, liên kết trang, neo và định tuyến ngôn ngữ. Cam kết các trang được tạo với nguồn của họ. Tài liệu xây dựng chỉ thay đổi các tệp cục bộ; triển khai trang web và xuất bản tải xuống là các hoạt động riêng biệt.

## Tài liệu liên quan

- [Tổng quan kỹ thuật](/docs/vi/architecture.md): kết nối gửi đi, dịch phiên, kỷ nguyên, hàng đợi giới hạn và lưu trữ mã thông báo
- [Usage](/docs/vi/getting-started.md): đăng nhập, thêm thiết bị, khởi động Agent, lệnh và shell
- Hướng dẫn triển khai: kho lưu trữ `docs/deployment.md` (chứa địa chỉ máy chủ; không được xuất bản trên trang này)
- [Giao thức truyền thông](/docs/vi/websocket-protocol.md)
- [Triển khai thiết bị đa nền tảng](/docs/vi/platform-installation.md)
