Files
inp2p/WEB_CONSOLE_PLAN.md

325 lines
7.5 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.
# INP2P Web 控制台开发方案
## 项目概览
- **后端**: Go + Gin (已集成在 inp2ps)
- **前端**: Vue 3 + Element Plus (推荐) 或 React + Tailwind
- **现有 API**: http://127.0.0.1:27183 (inp2ps 内置 HTTP)
- **数据格式**: JSON
---
## 一、API 对接清单
### 1. 基础信息 API
| 方法 | 路径 | 说明 | 返回示例 |
|------|------|------|----------|
| GET | `/api/v1/health` | 健康检查 + 节点数 | `{"status":"ok","version":"0.1.0","nodes":2}` |
| GET | `/api/v1/nodes` | 在线节点列表 | 见下方 Node 结构 |
| GET | `/api/v1/sdwans` | SDWAN 配置 | 见下方 SDWAN 结构 |
### 2. 节点管理 API
**NodeInfo 结构体** (Go):
```go
type NodeInfo struct {
Name string // 节点名称
User string // 用户名
Version string // 客户端版本
NATType int // NAT 类型: 1=Cone, 2=Symmetric, 0=Unknown
PublicIP string // 公网 IP
PublicPort int // 公网端口
LocalPort int // 本地端口
RelayEnabled bool // 是否开启中继
SuperRelay bool // 是否超级中继
LoginTime int64 // 登录时间戳
LastHeartbeat int64 // 最后心跳时间
IsOnline bool // 在线状态
}
```
**GET /api/v1/nodes** 返回:
```json
{
"nodes": [
{
"name": "hcss-ecs-8626",
"user": "",
"version": "0.1.0",
"natType": 1,
"publicIP": "189.1.238.33",
"publicPort": 49163,
"localPort": 49163,
"relayEnabled": false,
"superRelay": false,
"loginTime": 1772445856,
"lastHeartbeat": 1772445900,
"isOnline": true
}
]
}
```
### 3. SDWAN 管理 API
**SDWANConfig 结构体**:
```go
type SDWANConfig struct {
Enabled bool `json:"enabled"`
Name string `json:"name"`
GatewayCIDR string `json:"gatewayCIDR"` // 如 "10.10.0.0/24"
Mode string `json:"mode"` // "hub" | "mesh"
Routes []string `json:"routes"`
MTU int `json:"mtu,omitempty"`
Nodes []SDWANNode `json:"nodes"`
UpdatedAt int64 `json:"updatedAt"`
}
type SDWANNode struct {
Node string `json:"node"` // 节点名称
IP string `json:"ip"` // 虚拟 IP如 "10.10.0.2"
}
```
**GET /api/v1/sdwans** 返回:
```json
{
"enabled": true,
"name": "sdwan-main",
"gatewayCIDR": "10.10.0.0/24",
"mode": "mesh",
"routes": ["10.10.0.0/24"],
"nodes": [
{"node": "hcss-ecs-8626", "ip": "10.10.0.3"},
{"node": "i-6986ef49a8f84db00bcd0f24", "ip": "10.10.0.2"}
],
"updatedAt": 1772445856
}
```
**POST /api/v1/sdwan/edit** 请求体:
```json
{
"enabled": true,
"gatewayCIDR": "10.10.0.0/24",
"mode": "mesh",
"nodes": [
{"node": "nodeA", "ip": "10.10.0.2"},
{"node": "nodeB", "ip": "10.10.0.3"}
]
}
```
### 4. 待实现的 API (需新增)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/peers` | P2P 连接状态 (UDP/TCP/Relay) |
| POST | `/api/v1/connect` | 手动触发 P2P 连接 |
| GET | `/api/v1/relay/nodes` | 中继节点列表 |
| GET | `/api/v1/stats` | 流量统计 |
---
## 二、前端页面设计
### 1. 首页 / 仪表盘
- 显示服务器状态 (在线节点数、版本、运行时间)
- 显示 SDWAN 状态 (虚拟网络是否启用、在线节点)
- 快速操作按钮 (启用/禁用 SDWAN)
### 2. 节点管理页面
- 表格展示所有在线节点
- 列: 节点名 | NAT类型 | 公网IP | 中继状态 | 在线时长 | 最后心跳
- 支持搜索、过滤
- 节点详情弹窗 (连接信息、版本)
### 3. SDWAN 管理页面
- 当前配置展示 (网关 CIDR、模式、节点列表)
- 节点 IP 分配表单
- 启用/禁用开关
- 拓扑图 (可选): 显示节点间连接状态
### 4. 中继管理页面 (可选)
- 中继节点列表
- 带宽使用情况
- 负载均衡状态
---
## 三、前端技术栈建议
### 方案 A: Vue 3 + Element Plus (推荐)
```bash
# 创建项目
npm create vite@latest inp2p-console -- --template vue
cd inp2p-console
npm install element-plus axios vue-router@4
# 目录结构
src/
├── api/
│ └── index.js # API 调用封装
├── views/
│ ├── Dashboard.vue # 首页
│ ├── Nodes.vue # 节点管理
│ └── SDWAN.vue # SDWAN 管理
├── components/
└── App.vue
```
### 方案 B: React + Tailwind
```bash
npm create vite@latest inp2p-console -- --template react
npm install axios react-router-dom tailwindcss
```
---
## 四、后端集成方式
### 方案 1: 独立部署 (推荐)
前端打包后放入 `inp2ps` 同目录,通过 `-web-dir` 参数指定:
```bash
# 后端添加参数
./bin/inp2ps -ws-port 27183 -web-dir ./dist ...
```
**需新增代码** (`cmd/inp2ps/main.go`):
```go
var webDir string
flag.StringVar(&webDir, "web-dir", "", "Static web files directory")
// HTTP mux 中添加:
if webDir != "" {
mux.Handle("/", http.FileServer(http.Dir(webDir)))
}
```
### 方案 2: 独立端口
前端单独部署在不同端口 (如 8080),通过 API 调用后端。
---
## 五、开发步骤
### Step 1: 环境准备
```bash
# 1. 克隆项目
git clone https://gitea.king.nyc.mn/openclaw/inp2p.git
cd inp2p
# 2. 启动后端
./bin/inp2ps -ws-port 27183 -stun-udp1 27182 -stun-udp2 27183 \
-stun-tcp1 27180 -stun-tcp2 27181 \
-token 12063420751575908257
# 3. 验证 API
curl http://127.0.0.1:27183/api/v1/health
curl http://127.0.0.1:27183/api/v1/sdwans
```
### Step 2: 前端脚手架
```bash
npm create vite@latest web -- --template vue
cd web
npm install element-plus axios
```
### Step 3: API 封装
创建 `src/api/index.js`:
```javascript
import axios from 'axios'
const api = axios.create({
baseURL: 'http://127.0.0.1:27183/api/v1',
timeout: 5000
})
export const getHealth = () => api.get('/health')
export const getNodes = () => api.get('/nodes')
export const getSDWAN = () => api.get('/sdwans')
export const updateSDWAN = (data) => api.post('/sdwan/edit', data)
```
### Step 4: 页面开发
1. **Dashboard.vue**: 调用 `getHealth()`, `getSDWAN()`
2. **Nodes.vue**: 调用 `getNodes()`,表格展示
3. **SDWAN.vue**: 调用 `getSDWAN()`, `updateSDWAN()`
### Step 5: 后端增强
根据需要添加:
```go
// cmd/inp2ps/main.go
mux.HandleFunc("/api/v1/nodes", func(w http.ResponseWriter, r *http.Request) {
nodes := srv.GetOnlineNodes()
json.NewEncoder(w).Encode(map[string][]*NodeInfo{"nodes": nodes})
})
mux.HandleFunc("/api/v1/connect", func(w http.ResponseWriter, r *http.Request) {
// 触发 P2P 连接
})
```
---
## 六、关键代码位置
| 功能 | 文件 |
|------|------|
| HTTP 路由注册 | `cmd/inp2ps/main.go` |
| 节点管理 | `internal/server/server.go` |
| SDWAN 配置 | `internal/server/sdwan_api.go` |
| SDWAN 数据面 | `internal/server/sdwan.go` |
---
## 七、注意事项
1. **CORS**: 如果前后端分离,需要在后端添加 CORS 中间件
2. **认证**: 当前 API 无认证,生产环境需添加 token 验证
3. **WebSocket**: 可选添加 ws 实时推送节点状态变化
4. **静态文件**: 后端添加 `-web-dir` 支持前端嵌入
---
## 八、测试数据
当前测试环境:
- **服务器**: 127.0.0.1:27183 (token: 12063420751575908257)
- **SDWAN 配置**:
```json
{
"enabled": true,
"gatewayCIDR": "10.10.0.0/24",
"mode": "mesh",
"nodes": [
{"node": "hcss-ecs-8626", "ip": "10.10.0.3"},
{"node": "i-6986ef49a8f84db00bcd0f24", "ip": "10.10.0.2"}
]
}
```
---
完成上述清单后,你将拥有一个完整的 INP2P Web 管理控制台。