5.3 KiB
5.3 KiB
终端交互事件捕获功能
概述
现在socket通信系统已支持捕获和传输所有终端交互事件,包括:
- 键盘输入
- 鼠标点击、移动、滚轮
- 终端窗口大小变化
新增消息类型
typedef enum {
MSG_TYPE_INIT = 1, // 初始化连接
MSG_TYPE_WINDOW_SIZE_UPDATE = 2, // 窗口大小更新
MSG_TYPE_SERVER_RESPONSE = 3, // 服务器响应
MSG_TYPE_CLOSE = 4, // 关闭连接
MSG_TYPE_TERMINAL_INPUT = 5, // 终端输入(原始数据)
MSG_TYPE_TERMINAL_OUTPUT = 6, // 终端输出
MSG_TYPE_MOUSE_EVENT = 7, // 鼠标事件(结构化)
MSG_TYPE_KEY_EVENT = 8 // 键盘事件(结构化)
} MessageType;
鼠标事件结构
typedef struct {
uint32_t event_type; // 1=按下, 2=释放, 3=移动, 4=滚轮上, 5=滚轮下
uint32_t button; // 鼠标按钮(1=左键,2=中键,3=右键)
uint32_t x; // X坐标(列)
uint32_t y; // Y坐标(行)
uint32_t modifiers; // 修饰键(Shift, Ctrl, Alt等)
} MouseEvent;
工作原理
1. 鼠标跟踪启用
客户端通过ANSI转义序列启用终端的鼠标跟踪:
// 启用X11鼠标报告 + SGR扩展模式
const char* enable_seq = "\033[?1000h\033[?1002h\033[?1006h";
write(STDOUT_FILENO, enable_seq, strlen(enable_seq));
2. 事件解析
客户端监听标准输入的ANSI转义序列:
鼠标事件格式:\033[<b;x;yM 或 \033[<b;x;ym
- b: 按钮编码 + 修饰键
- x: 列坐标
- y: 行坐标
- M: 按下
- m: 释放
3. 独立输入线程
专门的线程持续监听stdin:
static void* terminal_input_thread(void* arg) {
while (!g_should_exit) {
// 使用poll等待输入
poll(&pfd, 1, 100);
// 读取数据
read(STDIN_FILENO, buf, sizeof(buf));
// 解析鼠标事件或发送原始输入
if (is_mouse_event(buf)) {
parse_and_send_mouse_event();
} else {
send_terminal_input();
}
}
}
4. Go服务端处理
服务端接收并记录所有交互事件:
switch msgType {
case MsgTypeTerminalInput:
logging.Debug("收到终端输入: %d bytes", len(payload))
case MsgTypeMouseEvent:
event := parseMouseEvent(payload)
logging.Info("鼠标事件 - 类型:%d, 按钮:%d, 位置:(%d,%d)",
event.EventType, event.Button, event.X, event.Y)
}
线程架构
客户端现在运行4个线程:
- 主线程:发送初始化消息,等待其他线程
- 响应监听线程:接收服务器响应
- 窗口监控线程:监听SIGWINCH信号
- 输入监听线程:监听stdin,捕获键盘和鼠标
使用示例
编译
cd execve_hook
make clean
make
测试
- 启动服务端:
cd go_service
sudo ./build/bash_go_service-amd64 daemon
- 运行测试程序:
cd execve_hook
./build/test_window_resize
-
在程序运行时:
- 调整终端窗口大小
- 点击鼠标
- 输入键盘字符
-
观察服务端日志输出所有事件
支持的鼠标模式
X11鼠标报告模式 (\033[?1000h)
- 捕获鼠标按键按下/释放
- 基本的鼠标位置报告
单元格运动跟踪 (\033[?1002h)
- 捕获鼠标移动(按下按钮时)
- 拖拽操作支持
SGR扩展模式 (\033[?1006h)
- 更好的大坐标支持(超过223列/行)
- 更清晰的按下/释放区分
应用场景
1. 用户行为分析
记录用户在终端中的所有操作,用于:
- 问题诊断
- 使用习惯分析
- 操作回放
2. 交互式帮助
根据用户的鼠标位置提供上下文帮助
3. 终端UI增强
捕获鼠标点击实现:
- 可点击的链接
- 交互式菜单
- 拖放操作
4. 会话记录
完整记录终端会话,包括:
- 所有输入输出
- 鼠标操作
- 窗口调整
性能考虑
- 输入延迟: < 10ms(poll超时100ms)
- CPU使用: 每个线程休眠,不占用CPU
- 内存: 每个连接 < 100KB
- 带宽: 鼠标事件20字节,键盘事件按实际输入
兼容性
终端支持
支持以下现代终端:
- ✓ xterm
- ✓ gnome-terminal
- ✓ konsole
- ✓ iTerm2
- ✓ Windows Terminal
- ✓ alacritty
- ✓ kitty
- ⚠ screen(部分支持)
- ⚠ tmux(需要配置)
禁用鼠标跟踪
如果不需要鼠标功能,可以注释掉:
// enable_mouse_tracking(STDOUT_FILENO);
调试
开启DEBUG模式查看所有事件:
make DEBUG=1
./build/test_window_resize
输出示例:
Mouse event: type=1, button=1, pos=(25,10)
Mouse event: type=2, button=1, pos=(25,10)
Terminal input: 5 bytes
Window size update sent to server
注意事项
- 非TTY环境:如果stdin不是TTY,鼠标跟踪会自动禁用
- 信号处理:正确处理SIGINT/SIGTERM以清理终端状态
- 原始模式:如需完全控制,可启用raw模式
- 终端恢复:程序退出时应恢复终端原始设置
扩展建议
- 触摸事件:支持触摸屏输入
- 手势识别:识别常见鼠标手势
- 快捷键绑定:自定义快捷键处理
- 剪贴板集成:捕获复制粘贴操作
- 焦点事件:终端获得/失去焦点通知