Files
boss_dp/README.md
ddrwode 4a520306b1 ha'ha
2026-02-12 16:46:01 +08:00

231 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 分布式浏览器控制后台
通过 **中央服务器 + Worker 代理** 架构,远程控制多台电脑上的比特浏览器,并使用 DrissionPage 执行自动化任务。
---
## 架构概览
```
前端 / Postman 中央服务器(第三台机器) 电脑 A / B
─────────────── ───────────────────── ──────────
REST API ──── HTTP ────→ FastAPI Server Worker Agent
├── Worker Manager ←── WebSocket ──┤
└── Task Dispatcher ──── WebSocket ──→ 比特浏览器
+ DrissionPage
```
- **中央服务器**:接收前端 API 请求,管理 Worker 状态,路由并派发任务
- **Worker 代理**:运行在每台电脑上,通过 WebSocket 连接服务器,接收任务后本地控制比特浏览器 + DrissionPage
---
## 快速开始
### 1. 安装依赖
```bash
pip install -r requirements.txt
```
### 2. 启动中央服务器
在第三台机器(或任一台能被其他机器访问的机器)上运行:
```bash
python -m server.main
```
默认监听 `0.0.0.0:8000`。可通过环境变量修改:
```bash
set SERVER_HOST=0.0.0.0
set SERVER_PORT=8000
python -m server.main
```
### 3. 启动 Worker每台电脑上各运行一个
**电脑 A**
```bash
python -m worker.main --server ws://服务器IP:8000/ws --worker-id pc-a --worker-name "电脑A"
```
**电脑 B**
```bash
python -m worker.main --server ws://服务器IP:8000/ws --worker-id pc-b --worker-name "电脑B"
```
Worker 启动后会自动:
1. 连接中央服务器
2. 上报本机比特浏览器窗口列表
3. 等待接收任务
> 注意:每台电脑需先启动比特浏览器客户端(默认 API 端口 54345
---
## 内网穿透(隧道)
项目内置 **独立 Python 隧道**,与 Worker 集成。线下电脑无需单独安装 frp 等工具,启动 Worker 时会同时建立隧道,将本机端口(如比特浏览器 API 54345暴露到云服务器便于从公网访问该机器上的服务。
- **云服务器**:随 `python -m server.main` 自动启动隧道服务端(控制端口 8001、流端口 8003、代理端口从 8010 起按 Worker 分配)。
- **线下电脑**Worker 启动时默认开启隧道客户端,连接云服务器并注册 `worker_id`,云上会为该 Worker 分配一个代理端口(如 8010、8011…。访问 `云服务器IP:8010` 即等价于访问该 Worker 本机的 `127.0.0.1:54345`
**环境变量(可选)**
| 位置 | 变量 | 默认值 | 说明 |
|------|------|--------|------|
| 服务器 | `TUNNEL_CONTROL_PORT` | 8001 | 隧道控制端口 |
| 服务器 | `TUNNEL_STREAM_PORT` | 8003 | 隧道流端口 |
| 服务器 | `TUNNEL_PROXY_BASE_PORT` | 8010 | 代理端口起始 |
| Worker | `TUNNEL_ENABLED` | 1 | 是否启用隧道 |
| Worker | `TUNNEL_SERVER` | (从 SERVER_WS_URL 解析) | 隧道服务端地址 |
| Worker | `TUNNEL_LOCAL_PORT` | 54345 | 暴露的本地端口 |
**禁用隧道**`python -m worker.main --no-tunnel ...`
---
## API 接口
### 查看在线 Worker
```
GET /api/workers
```
响应示例:
```json
[
{
"worker_id": "pc-a",
"worker_name": "电脑A",
"browsers": [
{"id": "abc123", "name": "BOSS主号", "remark": "张三"}
],
"online": true,
"current_task_id": null
}
]
```
### 提交任务
```
POST /api/tasks
Content-Type: application/json
{
"task_type": "boss_recruit",
"account_name": "BOSS主号",
"params": {
"job_title": "前端工程师",
"max_greet": 5
}
}
```
路由规则:
- 指定 `worker_id` → 直接发到该 Worker
- 指定 `account_name` → 自动找到拥有该浏览器的 Worker
- 两者都传 → `worker_id` 优先
### 查询任务状态
```
GET /api/tasks/{task_id}
```
### 查询任务列表
```
GET /api/tasks?worker_id=pc-a&status=success&limit=20
```
### 健康检查
```
GET /health
```
---
## 项目结构
```
boss_dp/
├── server/ # 中央服务器
│ ├── main.py # FastAPI 入口(含 WebSocket 端点)
│ ├── config.py # 服务器配置
│ ├── models.py # Pydantic 数据模型
│ ├── api/
│ │ ├── workers.py # Worker 查询 API
│ │ └── tasks.py # 任务提交与查询 API
│ └── core/
│ ├── worker_manager.py # Worker 注册、状态管理、账号映射
│ └── task_dispatcher.py # 任务路由与派发
├── worker/ # Worker 代理(每台电脑部署)
│ ├── main.py # 启动入口
│ ├── config.py # Worker 配置
│ ├── ws_client.py # WebSocket 客户端(心跳、重连)
│ ├── bit_browser.py # 比特浏览器 API 封装
│ ├── browser_control.py # DrissionPage 通用控制封装
│ └── tasks/
│ ├── base.py # 任务处理器基类
│ ├── registry.py # 处理器注册表
│ └── boss_recruit.py # BOSS 直聘招聘任务
├── common/
│ └── protocol.py # 共享消息协议
├── tunnel/ # 内网穿透(独立隧道,与 Worker 集成)
│ ├── __init__.py
│ ├── protocol.py # 隧道控制协议
│ ├── server.py # 隧道服务端(云上)
│ └── client.py # 隧道客户端(线下,随 Worker 启动)
├── requirements.txt
└── README.md
```
---
## 扩展新任务
1.`worker/tasks/` 下新建文件,继承 `BaseTaskHandler`
2. 实现 `execute` 方法
3.`common/protocol.py``TaskType` 中添加新类型
4.`worker/tasks/registry.py``register_all_handlers()` 中注册
```python
# worker/tasks/my_task.py
from worker.tasks.base import BaseTaskHandler
class MyTaskHandler(BaseTaskHandler):
task_type = "my_task"
async def execute(self, task_id, params, progress_cb):
await progress_cb(task_id, "开始执行...")
# ... 你的自动化逻辑 ...
return {"status": "done"}
```
---
## 配置项
### 服务器 (server/config.py)
| 环境变量 | 默认值 | 说明 |
|---------|--------|------|
| `SERVER_HOST` | `0.0.0.0` | 监听地址 |
| `SERVER_PORT` | `8000` | 监听端口 |
| `API_TOKEN` | (空) | 非空时校验 Authorization Header |
### Worker (worker/config.py)
| 环境变量 | 默认值 | 说明 |
|---------|--------|------|
| `SERVER_WS_URL` | `ws://127.0.0.1:8000/ws` | 服务器 WebSocket 地址 |
| `WORKER_ID` | `worker-1` | Worker 唯一标识 |
| `WORKER_NAME` | `本机` | Worker 显示名称 |
| `BIT_API_BASE` | `http://127.0.0.1:54345` | 比特浏览器本地 API |