feat(rdp): 新增 RDP 远程桌面/SMB/账单同步能力 + 清理编译产物
主要变更: - RDP 远程桌面:新增 backend/pkg/rdp(RDP 引擎 + credssp/display/rle/trace)、 backend/controller/rdp*(连接/凭证/文件/会话/实时)、frontend RDP 组件与 API - Windows SMB 文件传输:backend/pkg/winsmb - 云账单同步:backend/pkg/billingsync + billing_sync/aliyun_billing,前端账单详情 - Agent CLI Kubernetes 工具:kubernetes_action/get、pod_execute/logs - 服务器导入助手:server_import_helpers、ImportCredentialSettings - 国际化与组件重构(cloud/deploy/monitor/server/system 等多模块) - 清理编译产物二进制:移除 backend/server、backend/agent/bin/aiops-agent-* - .gitignore:新增 backend/agent/ 与 .cache/(避免 334MB go-build 缓存误入库) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
1 parent
777d9e4e71
commit
76ec9387f0
202 files changed
+16555
-2543
No files matched your search
@@ -0,0 +1,126 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Config 是后端 RDP 渲染引擎的连接配置,凭据只在服务端使用 // Logan.Li
|
||||
type Config struct {
|
||||
Host string
|
||||
Port int
|
||||
Username string
|
||||
Password string
|
||||
Domain string
|
||||
Security string
|
||||
Width int
|
||||
Height int
|
||||
MCSMode string
|
||||
Debug bool
|
||||
}
|
||||
|
||||
// ClientEvent 是浏览器发回后端的输入事件 // Logan.Li
|
||||
type ClientEvent struct {
|
||||
Type string `json:"type"`
|
||||
X int `json:"x,omitempty"`
|
||||
Y int `json:"y,omitempty"`
|
||||
Button int `json:"button,omitempty"`
|
||||
DeltaY int `json:"delta_y,omitempty"`
|
||||
Code string `json:"code,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
Down bool `json:"down,omitempty"`
|
||||
Width int `json:"width,omitempty"`
|
||||
Height int `json:"height,omitempty"`
|
||||
Text string `json:"text,omitempty"`
|
||||
}
|
||||
|
||||
// ServerFrame 是后端推给浏览器 Canvas 的统一帧协议 // Logan.Li
|
||||
type ServerFrame struct {
|
||||
Type string `json:"type"`
|
||||
X int `json:"x,omitempty"`
|
||||
Y int `json:"y,omitempty"`
|
||||
Width int `json:"width,omitempty"`
|
||||
Height int `json:"height,omitempty"`
|
||||
Image string `json:"image,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Text string `json:"text,omitempty"`
|
||||
RGBA []byte `json:"-"`
|
||||
}
|
||||
|
||||
// FrameSink 接收 RDP 引擎输出,控制器负责写入 WebSocket // Logan.Li
|
||||
type FrameSink interface {
|
||||
SendFrame(ServerFrame) error
|
||||
}
|
||||
|
||||
// Engine 隔离自研 RDP 协议实现,避免控制器关心握手和图形帧细节 // Logan.Li
|
||||
type Engine interface {
|
||||
Run(ctx context.Context, cfg Config, sink FrameSink, events <-chan ClientEvent) error
|
||||
}
|
||||
|
||||
// HandshakeInfo 记录轻量 RDP 第一阶段握手结果,用于前端诊断 // Logan.Li
|
||||
type HandshakeInfo struct {
|
||||
Address string
|
||||
SelectedProtocol string
|
||||
Duration time.Duration
|
||||
TLSCipher string
|
||||
CertSubject string
|
||||
}
|
||||
|
||||
// MemoryRecorder 保存图形帧摘要,后续可替换为 PNG/JPEG 序列录屏 // Logan.Li
|
||||
type MemoryRecorder struct {
|
||||
mu sync.Mutex
|
||||
events []ServerFrame
|
||||
limit int
|
||||
}
|
||||
|
||||
// NewMemoryRecorder 创建内存帧记录器,限制录屏摘要常驻内存大小 // Logan.Li
|
||||
func NewMemoryRecorder(limit int) *MemoryRecorder {
|
||||
if limit <= 0 {
|
||||
limit = 500
|
||||
}
|
||||
return &MemoryRecorder{limit: limit}
|
||||
}
|
||||
|
||||
// Append 记录一帧 RDP 输出,超过上限时丢弃最早帧 // Logan.Li
|
||||
func (r *MemoryRecorder) Append(frame ServerFrame) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
// 实时帧只用于 WebSocket 推送,审计内存索引保留元数据避免拖动窗口时触发大对象 GC。 // Logan.Li
|
||||
frame.RGBA = nil
|
||||
if frame.Type == "bitmap" {
|
||||
frame.Image = ""
|
||||
}
|
||||
if len(r.events) >= r.limit {
|
||||
copy(r.events, r.events[1:])
|
||||
r.events[len(r.events)-1] = frame
|
||||
return
|
||||
}
|
||||
r.events = append(r.events, frame)
|
||||
}
|
||||
|
||||
// AppendSnapshot 记录节流后的图形快照,用于 RDP 历史回放。 // Logan.Li
|
||||
func (r *MemoryRecorder) AppendSnapshot(frame ServerFrame) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
frame.RGBA = nil
|
||||
if len(r.events) >= r.limit {
|
||||
copy(r.events, r.events[1:])
|
||||
r.events[len(r.events)-1] = frame
|
||||
return
|
||||
}
|
||||
r.events = append(r.events, frame)
|
||||
}
|
||||
|
||||
// JSON 输出前端回放需要的轻量帧序列 // Logan.Li
|
||||
func (r *MemoryRecorder) JSON() string {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
b, _ := json.Marshal(struct {
|
||||
Version int `json:"version"`
|
||||
Time time.Time `json:"time"`
|
||||
Frames []ServerFrame `json:"frames"`
|
||||
}{Version: 1, Time: time.Now(), Frames: r.events})
|
||||
return string(b)
|
||||
}
|
||||
Reference in new issue
Block a user