mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-22 09:58:06 +00:00
- 抽取设备桥 WS 协议层为共享库 (internal/devicebridge/client/)
- CLI 补齐 11 项 caps 能力(screensee/screensue/speakeruse/camerasue/...)
- GUI 新增 omniparse 能力(Windows UIA 窗口解析)
- GUI computeruse 改用 koffi 直接调用 user32.dll,不再依赖 PowerShell C# 编译
- GUI computeruse JSON 解析兼容非标准格式 {x:500,y:300}
- 新增 mock-server 用于本地测试设备桥协议
- 新增 GUI DLL 桥接模块 (devicebridge_dll.js)
101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
package client
|
||
|
||
// BinaryChunker 提供二进制数据分块传输功能。
|
||
// 用于将大体积数据(如录像 mp4、大图片)按分块协议发送。
|
||
// 协议:
|
||
// cmd_data_start {op, req_id, kind, total, chunk_size, mime} —— 文本帧
|
||
// <N 个二进制帧 0x2> —— data bytes
|
||
// cmd_data_end {op, req_id, status:ok|error, error?} —— 文本帧
|
||
|
||
const (
|
||
// DefaultChunkSize 默认分块大小(8KB)
|
||
DefaultChunkSize = 8192
|
||
|
||
// MaxBinaryFrameSize 二进制帧最大大小(8MB)
|
||
MaxBinaryFrameSize = 8 << 20
|
||
)
|
||
|
||
// ChunkCallback 分块发送回调,用于逐块处理。
|
||
type ChunkCallback func(chunk []byte) error
|
||
|
||
// ChunkData 将数据按指定大小分块。
|
||
func ChunkData(data []byte, chunkSize int) [][]byte {
|
||
if chunkSize <= 0 {
|
||
chunkSize = DefaultChunkSize
|
||
}
|
||
total := len(data)
|
||
var chunks [][]byte
|
||
for off := 0; off < total; off += chunkSize {
|
||
end := off + chunkSize
|
||
if end > total {
|
||
end = total
|
||
}
|
||
chunks = append(chunks, data[off:end])
|
||
}
|
||
return chunks
|
||
}
|
||
|
||
// SendChunked 使用回调逐块发送数据。
|
||
func SendChunked(data []byte, chunkSize int, fn ChunkCallback) error {
|
||
if chunkSize <= 0 {
|
||
chunkSize = DefaultChunkSize
|
||
}
|
||
chunks := ChunkData(data, chunkSize)
|
||
for _, chunk := range chunks {
|
||
if err := fn(chunk); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// ===== 数据聚合(接收端) =====
|
||
|
||
// DataAccumulator 聚合从设备接收的二进制分块数据。
|
||
type DataAccumulator struct {
|
||
ReqID string
|
||
Kind string
|
||
MIME string
|
||
Total int
|
||
Got int
|
||
Chunks [][]byte
|
||
}
|
||
|
||
// NewDataAccumulator 创建数据聚合器。
|
||
func NewDataAccumulator(reqID, kind, mime string, total int) *DataAccumulator {
|
||
return &DataAccumulator{
|
||
ReqID: reqID,
|
||
Kind: kind,
|
||
MIME: mime,
|
||
Total: total,
|
||
Chunks: make([][]byte, 0),
|
||
}
|
||
}
|
||
|
||
// Append 追加一块数据。
|
||
func (da *DataAccumulator) Append(chunk []byte) {
|
||
da.Chunks = append(da.Chunks, chunk)
|
||
da.Got += len(chunk)
|
||
}
|
||
|
||
// Assemble 聚合所有分块为完整数据。
|
||
func (da *DataAccumulator) Assemble() []byte {
|
||
total := 0
|
||
for _, c := range da.Chunks {
|
||
total += len(c)
|
||
}
|
||
data := make([]byte, 0, total)
|
||
for _, c := range da.Chunks {
|
||
data = append(data, c...)
|
||
}
|
||
return data
|
||
}
|
||
|
||
// ExceededLimit 检查是否超出限制(声明的 2 倍或硬上限 64MB)。
|
||
func (da *DataAccumulator) ExceededLimit() bool {
|
||
limit := da.Total*2 + 1024
|
||
if limit < 64<<20 {
|
||
limit = 64 << 20
|
||
}
|
||
return da.Got > limit
|
||
} |