| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- 借助MQTT实现远程控制Linux设备的SSH服务端和客户端
- 作者:niujiuru 日期:2026-01-20
- 1, 整体使用JSONRPC2.0 OVER MQTT的技术方案来架构
- 2,服务端使用:
- - 在具体的项目代码中调用该模块的: “ModuleInit()” 函数启动初始化、安装和运行
- - 在具体的项目代码中调用该模块的: “ModuleExit()” 函数完成退出、停止服务运行
- 3,服务端原理:
- - 服务端启动时,会连接到MQTT Broker,订阅主题:/yfkj/device/rpc/imei/cmd,接收来自客户端的指令
- - 服务端启动时,会连接到MQTT Broker,发布主题:/yfkj/device/rpc/imei/ack,向客户端发送指令结果
- 4,客户端使用:
- - 会编译生成可执行程序“yfkj_ssh_client”,目前支持Linux64和Windows64上位机
- - 通过配置文件配置MQTT Broker的地址、用户名、密码以及一些耗时命令的超时时间
- 5,客户端原理:
- - 客户端启动时,会连接到MQTT Broker,发布主题:/yfkj/device/rpc/imei/cmd,向服务端发送指令请求
- - 客户端启动时,会连接到MQTT Broker,订阅主题:/yfkj/device/rpc/imei/ack,接收服务端的指令结果
- 6,总体架构图:
- ┌────────────────────────────┐
- │ Shell Client │
- │ │
- │ stdin ──> JSON-RPC call │
- │ Ctrl+C ─> JSON-RPC notify │
- │ │
- │ prompt 显示 cwd │
- └──────────────┬─────────────┘
- │
- JSON-RPC 2.0 over MQTT
- │
- ┌──────────────▼─────────────┐
- │ Shell Server │
- │ │
- │ Executor (session级) │
- │ ├─ cwd │
- │ ├─ Exec(cmd) │
- │ ├─ Interrupt() │
- │ │
- │ process group (pgid) │
- │ └─ kill(-pgid, SIGINT) │
- └────────────────────────────┘
- 6,执行流程图:
- ┌──────────────────────────────────────────┐
- │ Remote Client │
- │ (Web / App / CLI 运维平台) │
- └───────────────┬──────────────────────────┘
- │ JSON-RPC 2.0
- | - executor.ping
- │ - executor.exec
- │ - executor.interrupt
- │ - executor.close
- v
- ┌──────────────────────────────────────────┐
- │ MQTT Broker │
- │ (QoS1 / KeepAlive / Reconnect) │
- └───────────────┬──────────────────────────┘
- │ MQTT Message
- │ Topic: /yfkj/device/rpc/{imei}/cmd
- v
- ┌──────────────────────────────────────────┐
- │ sshd / MQTTCoupler │
- │ │
- │ Transport & RPC Adapter Layer │
- │ --------------------------------------- │
- │ - MQTT 连接管理 │
- │ - JSON-RPC 解析 / 校验 │
- │ - 方法分发 (Method Dispatch) │
- │ │
- └───────────────┬──────────────────────────┘
- │ 串行 / 单 Session
- v
- ┌──────────────────────────────────────────┐
- │ shell.Executor │
- │ │
- │ Session State Layer (≈ SSH Session) │
- │ --------------------------------------- │
- │ State: │
- │ - cwd : 当前工作目录 │
- │ - pg : 当前前台进程组 │
- │ │
- │ Built-in Commands │
- │ --------------------------------------- │
- │ - cd │
- │ - pwd │
- │ │
- │ Control Interface │
- │ --------------------------------------- │
- │ Exec() : 启动命令 │
- │ Interrupt() : Ctrl+C (SIGINT) │
- │ │
- └───────────────┬──────────────────────────┘
- │ 单次命令执行
- v
- ┌──────────────────────────────────────────┐
- │ executeInternal │
- │ │
- │ Process Lifecycle Layer │
- │ --------------------------------------- │
- │ - fork/exec │
- │ - 新进程组 (setpgid) │
- │ - stdout / stderr 限流 │
- │ - 超时控制 (context timeout) │
- │ - SIGTERM → SIGKILL │
- │ │
- └───────────────┬──────────────────────────┘
- │ MQTT Message
- | Topic: /yfkj/device/rpc/{imei}/ack
- v
- ┌──────────────────────────────────────────┐
- │ Linux Kernel │
- │ │
- │ - Process Group │
- │ - Signal Delivery │
- │ - Exit Status │
- └──────────────────────────────────────────┘
- 8, 取消流程图:Ctrl+C
- Remote Client
- │
- │ shell.execute
- v
- ┌───────────────┐
- │ sshd │
- └──────┬────────┘
- │
- v
- ┌───────────────────────────┐
- │ shell.Executor │
- │ │
- │ Exec(): │
- │ - 设置 p.Dir = cwd │
- │ - 注册前台进程组 pg │
- │ │
- └──────┬────────────────────┘
- │
- v
- ┌───────────────────────────┐
- │ executeInternal │
- │ │
- │ - Start cmd │
- │ - setpgid │
- │ - onStart(pg) │◄──────┐
- │ │ │
- │ - wait / timeout │ │
- └──────┬────────────────────┘ │
- │ │
- v │
- Command Running │
- │
- Remote Client Ctrl+C │
- │ │
- │ shell.interrupt │
- v │
- ┌───────────────┐ │
- │ sshd │ │
- └──────┬────────┘ │
- │ │
- v │
- ┌───────────────────────────┐ │
- │ Executor.Interrupt() │ │
- │ → SIGINT to -pgid │───────┘
- └───────────────────────────┘
|