Tổng quan kiến trúc
Tệp nguồn liên quan
Trang này được tạo dựa trên các tệp nguồn sau:
- main.go
- core/app.go
- core/bind.go
- frontend/src/main.ts
- frontend/wailsjs/go/core/Bind.js
- wails.json
- core/rule.go
- core/proxy.go
- core/resource.go
- core/system_linux.go
- frontend/src/router/index.ts
- frontend/src/stores/index.ts
- go.mod
- frontend/package.json
- frontend/wailsjs/runtime/package.json
- core/aes.go
- core/http.go
- core/utils.go
- core/config.go
- core/logger.go
Dự án res-downloader là một ứng dụng desktop đa nền tảng được xây dựng trên nền tảng Wails v2, kết hợp sức mạnh của Golang cho backend xử lý nặng và Vue.js 3 cho giao diện người dùng hiện đại. Ứng dụng hoạt động như một công cụ嗅探 (sniffing) và tải xuống tài nguyên mạng, sử dụng HTTP Proxy cục bộ để chặn và phân tích lưu lượng mạng.
Tổng quan về công nghệ và khung ứng dụng
Dự án sử dụng Wails v2 như một framework chính để xây dựng ứng dụng desktop. Wails cho phép đóng gói ứng dụng Go backend cùng với frontend hiện đại (Vue.js) thành một executable duy nhất, giao tiếp thông qua cơ chế binding tự động (main.go:1-43).
Công nghệ Backend
Backend được viết bằng Go 1.22+, tận dụng các thư viện sau:
| Thư viện | Mục đích |
|---|---|
| github.com/wailsapp/wails/v2 | Framework desktop chính |
| github.com/elazarl/goproxy | HTTP Proxy và MITM |
| github.com/rs/zerolog | Logging có cấu trúc |
| golang.org/x/net | Xử lý mạng nâng cao |
Công nghệ Frontend
Frontend sử dụng Vue 3 ecosystem với các thư viện:
- Vue 3: Framework UI chính
- Pinia: State management
- Vue Router: Định tuyến ứng dụng
- TypeScript: Type safety
Kiến trúc Backend và Luồng xử lý Proxy
Tổng quan kiến trúc hệ thống
正在加载图表渲染器...
Giải thích kiến trúc:
-
Frontend Layer: Giao diện người dùng được xây dựng bằng Vue 3, sử dụng Pinia để quản lý trạng thái và WailsJS để gọi các phương thức Go backend thông qua cơ chế binding tự động (frontend/wailsjs/go/core/Bind.js:1-15).
-
Backend Layer: Core logic được triển khai trong package
core, bao gồm HTTP server, Proxy engine, Resource manager và các thành phần khác. -
System Layer: Tương tác với hệ điều hành để cài đặt proxy hệ thống, certificate và quản lý file tải xuống.
HTTP Server và Proxy Engine
HTTP Server được khởi tạo trong hàm initHttpServer() và lắng nghe trên host:port được cấu hình. Server này đóng vai trò kép: xử lý API requests nội bộ và chuyển tiếp các requests khác đến Proxy engine (core/http.go:29-54).
go1// Định tuyến request dựa trên Host header 2if r.Host == "127.0.0.1:"+globalConfig.Port && HandleApi(w, r) { 3 // Xử lý API nội bộ 4} else { 5 proxyOnce.Proxy.ServeHTTP(w, r) // Chuyển đến Proxy 6}
Proxy Engine sử dụng thư viện goproxy với cấu hình Transport tùy chỉnh, hỗ trợ upstream proxy và timeout settings (core/proxy.go:110-149):
- DialContext Timeout: 60 giây
- TLSHandshake Timeout: 60 giây
- IdleConn Timeout: 30 giây
Hệ thống Plugin và Rule Matching
Proxy sử dụng cơ chế Plugin để xử lý các requests đặc thù theo domain. Khi một request đến, Proxy sẽ khớp domain với plugin registry và gọi OnRequest của plugin nếu tìm thấy (core/proxy.go:136-149).
Rule Engine chịu trách nhiệm lọc URL dựa trên các quy tắc được định nghĩa trong cấu hình. Rules hỗ trợ:
- Wildcard matching (
*) - Negative matching (tiền tố
!) - Regex patterns
Quản lý tài nguyên và Tải xuống
Resource Manager
Resource Manager (core/resource.go) quản lý vòng đời của các tài nguyên được phát hiện và tải xuống. Nó sử dụng sync.Map để tracking các media đã đánh dấu và các tác vụ tải xuống đang chạy (core/resource.go:30-99).
Các chức năng chính:
| Hàm | Mục đích |
|---|---|
mediaIsMarked(key) | Kiểm tra media đã được đánh dấu chưa |
markMedia(key) | Đánh dấu media để tránh trùng lặp |
cancel(id) | Hủy bỏ tác vụ tải xuống theo ID |
clear() | Xóa tất cả đánh dấu |
MIME Type Handling
Cấu hình mặc định định nghĩa một MimeMap toàn diện hỗ trợ nhiều định dạng file (core/config.go:119-157):
Hình ảnh: png, webp, jpeg, gif, avif, bmp, tiff, heic, ico, svg, psd, jp2, apng
Âm thanh: mp3, wav, aiff, aac, ogg, flac, midi, wma, opus, webm, m4a, amr
Video: mp4, webm, ogv, avi, mpeg, mov, wmv
Kiến trúc Frontend và Giao tiếp dữ liệu
State Management với Pinia
Store chính (useIndexStore) quản lý trạng thái ứng dụng bao gồm app info, global config, proxy status và environment info (frontend/src/stores/index.ts:1-65).
typescript1// Cấu trúc globalConfig trong store 2const globalConfig = ref<appType.Config>({ 3 Theme: "lightTheme", 4 Locale: "zh", 5 Host: "0.0.0.0", 6 Port: "8899", 7 Quality: 0, 8 SaveDirectory: "", 9 // ... các field khác 10})
Wails Binding Bridge
Cầu nối giao tiếp giữa Frontend và Backend được thực hiện qua Wails bindings. Struct Bind trong Go expose các phương thức mà JavaScript có thể gọi (core/bind.go:9-25):
| Go Method | JS Function | Mục đích |
|---|---|---|
Config() | bind.Config() | Lấy cấu hình hiện tại |
AppInfo() | bind.AppInfo() | Lấy thông tin ứng dụng |
ResetApp() | bind.ResetApp() | Reset ứng dụng |
Định tuyến ứng dụng
Vue Router được cấu hình với hai route chính (frontend/src/router/index.ts:1-31):
/index: Trang chủ vớikeepAlive: true/setting: Trang cài đặt vớikeepAlive: false
Cấu hình Bảo mật và Tiện ích hệ thống
Quản lý cấu hình
Config Manager khởi tạo cấu hình mặc định và tải cấu hình người dùng từ file JSON. Cấu hình được lưu trữ trong thư mục user data của ứng dụng (core/config.go:46-83).
Cấu hình mặc định:
go1defaultConfig := &Config{ 2 Theme: "lightTheme", 3 Locale: "zh", 4 Host: "127.0.0.1", 5 Port: "8899", 6 TaskNumber: runtime.NumCPU() * 2, 7 DownNumber: 3, 8 UserAgent: "Mozilla/5.0 ...", 9 MimeMap: getDefaultMimeMap(), 10 Rule: "*", 11}
Mã hóa AES
Ứng dụng triển khai AES CBC encryption để bảo vệ dữ liệu nhạy cảm (core/aes.go:16-72):
- Encrypt: Tạo IV ngẫu nhiên, padding PKCS7, encode base64
- Decrypt: Decode base64, extract IV, unpad plaintext
Tương tác hệ điều hành
App struct quản lý vòng đời ứng dụng và tương tác với hệ điều hành (core/app.go:129-166):
- Startup: Khởi tạo context, chạy HTTP server
- OnExit: Hủy system proxy, đóng logger, reset app nếu cần
- OpenSystemProxy: Cài đặt proxy hệ thống
- UnsetSystemProxy: Gỡ bỏ proxy hệ thống
Luồng dữ liệu và Chuỗi gọi quan trọng
Luồng xử lý Request
正在加载图表渲染器...
Giải thích luồng:
-
Request Entry: Tất cả HTTP/HTTPS requests từ browser đi qua proxy tại port 8899 (core/http.go:37-54).
-
Routing Decision: Server kiểm tra Host header để xác định đây là API request hay proxy request thông thường.
-
Plugin Processing: Nếu có plugin đăng ký cho domain, plugin có thể modify request/response (core/proxy.go:136-149).
-
Rule Matching: URL được kiểm tra against rule set để xác định có nên extract resource hay không (core/rule.go:22-61).
-
Resource Extraction & Download: Nếu URL match, resource info được extract và tác vụ download được khởi tạo (core/resource.go:30-99).
Luồng khởi tạo ứng dụng
正在加载图表渲染器...
Mối quan hệ phụ thuộc giữa các module
正在加载图表渲染器...
Giải thích dependencies:
-
main.go là entry point duy nhất, khởi tạo App và Bind structs (main.go:29-43).
-
App struct là trung tâm của backend, quản lý lifecycle và giữ references đến các singleton khác như Config, Logger, System (core/app.go:42-172).
-
Bind struct expose các phương thức cho frontend thông qua Wails bindings, gọi đến App và Config (core/bind.go:9-25).
-
HttpServer sử dụng Proxy để xử lý requests, Proxy sử dụng RuleSet để filter và Resource để quản lý downloads.
-
Frontend giao tiếp với backend exclusively thông qua WailsJS bindings, không có direct HTTP calls đến backend API.
Các quyết định thiết kế và đánh đổi
1. Wails Framework Selection
Lý do chọn: Wails cung cấp khả năng đóng gói ứng dụng Go với frontend hiện đại thành một binary duy nhất, loại bỏ nhu cầu external web server hay runtime dependencies.
Trade-off: Giới hạn trong việc sử dụng web technologies cho UI, không thể sử dụng native UI components trực tiếp.
2. Singleton Pattern cho Core Modules
Lý do chọn: Đơn giản hóa state management và đảm bảo consistency across application.
Trade-off: Khó khăn trong unit testing và potential concurrency issues nếu không xử lý cẩn thận.
3. HTTP Proxy Architecture
Lý do chọn: Cho phép sniff tất cả HTTP/HTTPS traffic mà không cần browser extension hay system hooks.
Trade-off: Yêu cầu cài đặt CA certificate cho HTTPS interception, có thể gây confusion cho users không kỹ thuật.
4. Go-Vue Communication via Bindings
Lý do chọn: Type-safe communication, automatic serialization/deserialization, better performance than HTTP API.
Trade-off: Tightly coupled frontend và backend, khó thay thế một trong hai independently.
5. File-based Configuration Storage
Lý do chọn: Đơn giản, human-readable, dễ backup và migrate.
Trade-off: Không có built-in encryption cho sensitive data (được address bằng AES encryption riêng).
6. Sync.Map cho Resource Tracking
Lý do chọn: Thread-safe mà không cần explicit locking, phù hợp cho read-heavy workloads.
Trade-off: Không phù hợp cho scenarios cần consistent snapshots hay complex transactions.
7. Plugin-based Request Handling
Lý do chọn: Extensibility, cho phép thêm support cho new platforms mà không modify core code.
Trade-off: Additional complexity, potential performance overhead từ plugin lookup.
Bảng tổng hợp công nghệ
| Công nghệ | Phiên bản | Mục đích | Lý do chọn | Thay thế khả thi |
|---|---|---|---|---|
| Wails v2 | 2.10.1 | Desktop framework | Cross-platform, single binary, Go native | Electron, Tauri |
| Go | 1.22+ | Backend language | Performance, concurrency, single binary | Rust, C++ |
| Vue 3 | Latest | Frontend framework | Modern, reactive, TypeScript support | React, Svelte |
| Pinia | Latest | State management | Vue 3 native, TypeScript friendly | Vuex, Redux |
| goproxy | 1.7.2 | HTTP Proxy | MITM support, Go native | mitmproxy |
| zerolog | 1.33.0 | Logging | Zero-allocation, structured logging | logrus, zap |
| AES-CBC | N/A | Encryption | Standard, widely supported | AES-GCM, ChaCha20 |
| Vue Router | 4.x | Routing | Vue 3 native, hash mode | React Router |
| TypeScript | 5.x | Type safety | Catch errors at compile time | JavaScript |
Cấu hình quan trọng và Luồng khởi động
Cấu hình Wails
File wails.json định nghĩa metadata và build configuration (wails.json:1-20):
json1{ 2 "name": "res-downloader", 3 "outputfilename": "res-downloader", 4 "frontend:install": "npm install", 5 "frontend:build": "npm run build", 6 "info": { 7 "productVersion": "3.1.3" 8 } 9}
Luồng khởi động chi tiết
-
main.go được thực thi, gọi
core.GetApp()để khởi tạo App singleton với embedded assets và wails.json content (main.go:29-31). -
core.NewBind() tạo Bind instance để expose methods cho frontend (main.go:32).
-
wails.Run() được gọi với options bao gồm window dimensions, menu, asset server với middleware, và lifecycle callbacks (main.go:43-96).
-
OnStartup callback được trigger, khởi tạo context và chạy HTTP server trong goroutine (core/app.go:129-132).
-
Frontend được mount, Pinia store init được gọi, thực hiện các Wails binding calls để fetch AppInfo và Config (frontend/src/stores/index.ts:49-65).
-
HTTP Server bắt đầu lắng nghe, sẵn sàng handle API và proxy requests (core/http.go:37-54).
