Feature: Web remote terminal (xterm.js + mobile UX polish)

This commit is contained in:
yuanyuanxiang
2026-05-14 23:57:48 +02:00
parent 5d9554780f
commit 5a92c3306f
11 changed files with 953 additions and 8 deletions

View File

@@ -247,6 +247,27 @@ public:
void UnregisterScreenContext(uint64_t device_id);
CONTEXT_OBJECT* GetScreenContext(uint64_t device_id);
// ========== Web Terminal (Phase 1: 1 user per device) ==========
// Web 终端会话桥:把浏览器端 xterm.js ↔ 客户端 shell 子上下文连起来。
// 设计:每台主机最多一个 Web 终端会话;如果别的浏览器请求同一台主机的终端,
// 拒绝UX 上后续可改成共享只读)。
// 生命周期term_open → COMMAND_SHELL → 客户端建子上下文 → MessageHandle
// 看到 TOKEN_TERMINAL_START / TOKEN_SHELL_START + IsTermPending(d) →
// 调 RegisterTerminalContext 接管,跳过 MFC dialog 打开。
// 浏览器侧入口
void HandleTermOpen(void* ws_ptr, const std::string& msg);
void HandleTermInput(void* ws_ptr, const std::string& msg);
void HandleTermResize(void* ws_ptr, const std::string& msg);
void HandleTermClose(void* ws_ptr, const std::string& msg);
// MessageHandle 向 WebService 询问 / 移交的钩子
bool IsTermPending(uint64_t device_id); // 决定是否要拦截 dialog 打开
void RegisterTerminalContext(uint64_t device_id, CONTEXT_OBJECT* ctx, bool isPty);
bool IsTerminalContext(CONTEXT_OBJECT* ctx); // 是否是 Web 终端持有的上下文
void OnTerminalData(CONTEXT_OBJECT* ctx, const BYTE* data, ULONG len);// 把 shell 输出泵到对应 web client
void OnTerminalClosed(CONTEXT_OBJECT* ctx); // shell 子上下文断开时清理
private:
// Screen context registry: device_id -> ScreenManager's CONTEXT_OBJECT
std::map<uint64_t, CONTEXT_OBJECT*> m_ScreenContexts;
@@ -255,6 +276,21 @@ private:
// MFC triggered devices: dialogs created by MFC should always be visible
std::set<uint64_t> m_MfcTriggeredDevices;
std::mutex m_MfcTriggeredMutex;
// Web 终端会话状态
struct WebTermSession {
void* ws_ptr; // browser WebSocket
uint64_t device_id;
CONTEXT_OBJECT* shell_ctx; // shell 子上下文(首条消息抵达后才填)
bool is_pty; // true=TOKEN_TERMINAL现代 PTY, false=TOKEN_SHELL老 cmd 管道)
};
std::map<uint64_t, WebTermSession> m_TermSessions; // by device_id
std::map<CONTEXT_OBJECT*, uint64_t> m_TermContextToDevice; // 反查 ctx → device_id
std::set<uint64_t> m_TermPending; // 已发 COMMAND_SHELL 待响应
std::mutex m_TermMutex;
// 内部清理(已持锁版本)
void CloseTermSessionLocked(uint64_t device_id);
};
// Global accessor