feat: add remote screenshot and shell execution capabilities
Some checks failed
Build Multi-Platform Binaries / build-frontend (push) Failing after 16s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Has been skipped
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Has been skipped
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Has been skipped
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Has been skipped
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Has been skipped
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Has been skipped
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Has been skipped
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Has been skipped
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Has been skipped
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Has been skipped
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Has been skipped

- Add screenshot capture API with quality control
- Add remote shell command execution with timeout
- Implement client-side handlers for screenshot and shell requests
- Add Web UI components for screenshot viewing and shell terminal
- Support auto-refresh for screenshot monitoring
- Add shell command history navigation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 21:33:09 +08:00
parent a9ca714b24
commit 5cee8daabc
11 changed files with 674 additions and 9 deletions

View File

@@ -1975,3 +1975,101 @@ func (s *Server) GetClientSystemStats(clientID string) (*protocol.SystemStatsRes
return &stats, nil
}
// GetClientScreenshot 获取客户端截图
func (s *Server) GetClientScreenshot(clientID string, quality int) (*protocol.ScreenshotResponse, error) {
s.mu.RLock()
cs, ok := s.clients[clientID]
s.mu.RUnlock()
if !ok {
return nil, fmt.Errorf("client %s not online", clientID)
}
stream, err := cs.Session.Open()
if err != nil {
return nil, err
}
defer stream.Close()
// 设置超时
stream.SetDeadline(time.Now().Add(15 * time.Second))
// 发送请求
req := protocol.ScreenshotRequest{Quality: quality}
msg, _ := protocol.NewMessage(protocol.MsgTypeScreenshotRequest, req)
if err := protocol.WriteMessage(stream, msg); err != nil {
return nil, err
}
// 读取响应
resp, err := protocol.ReadMessage(stream)
if err != nil {
return nil, err
}
if resp.Type != protocol.MsgTypeScreenshotResponse {
return nil, fmt.Errorf("unexpected response type: %d", resp.Type)
}
var screenshot protocol.ScreenshotResponse
if err := resp.ParsePayload(&screenshot); err != nil {
return nil, err
}
if screenshot.Error != "" {
return nil, fmt.Errorf("screenshot failed: %s", screenshot.Error)
}
return &screenshot, nil
}
// ExecuteClientShell 执行客户端 Shell 命令
func (s *Server) ExecuteClientShell(clientID, command string, timeout int) (*protocol.ShellExecuteResponse, error) {
s.mu.RLock()
cs, ok := s.clients[clientID]
s.mu.RUnlock()
if !ok {
return nil, fmt.Errorf("client %s not online", clientID)
}
stream, err := cs.Session.Open()
if err != nil {
return nil, err
}
defer stream.Close()
// 设置超时 (比命令超时长一点)
if timeout <= 0 {
timeout = 30
}
stream.SetDeadline(time.Now().Add(time.Duration(timeout+5) * time.Second))
// 发送请求
req := protocol.ShellExecuteRequest{
Command: command,
Timeout: timeout,
}
msg, _ := protocol.NewMessage(protocol.MsgTypeShellExecuteRequest, req)
if err := protocol.WriteMessage(stream, msg); err != nil {
return nil, err
}
// 读取响应
resp, err := protocol.ReadMessage(stream)
if err != nil {
return nil, err
}
if resp.Type != protocol.MsgTypeShellExecuteResponse {
return nil, fmt.Errorf("unexpected response type: %d", resp.Type)
}
var result protocol.ShellExecuteResponse
if err := resp.ParsePayload(&result); err != nil {
return nil, err
}
return &result, nil
}