readme.txt 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. 借助MQTT实现远程控制Linux设备的SSH服务端和客户端
  2. 作者:niujiuru 日期:2026-01-20
  3. 1, 整体使用JSONRPC2.0 OVER MQTT的技术方案来架构
  4. 2,服务端使用:
  5. - 在具体的项目代码中调用该模块的: “ModuleInit()” 函数启动初始化、安装和运行
  6. - 在具体的项目代码中调用该模块的: “ModuleExit()” 函数完成退出、停止服务运行
  7. 3,服务端原理:
  8. - 服务端启动时,会连接到MQTT Broker,订阅主题:/yfkj/device/rpc/imei/cmd,接收来自客户端的指令
  9. - 服务端启动时,会连接到MQTT Broker,发布主题:/yfkj/device/rpc/imei/ack,向客户端发送指令结果
  10. 4,客户端使用:
  11. - 会编译生成可执行程序“yfkj_ssh_client”,目前支持Linux64和Windows64上位机
  12. - 通过配置文件配置MQTT Broker的地址、用户名、密码以及一些耗时命令的超时时间
  13. 5,客户端原理:
  14. - 客户端启动时,会连接到MQTT Broker,发布主题:/yfkj/device/rpc/imei/cmd,向服务端发送指令请求
  15. - 客户端启动时,会连接到MQTT Broker,订阅主题:/yfkj/device/rpc/imei/ack,接收服务端的指令结果
  16. 6,总体架构图:
  17. ┌────────────────────────────┐
  18. │ Shell Client │
  19. │ │
  20. │ stdin ──> JSON-RPC call │
  21. │ Ctrl+C ─> JSON-RPC notify │
  22. │ │
  23. │ prompt 显示 cwd │
  24. └──────────────┬─────────────┘
  25. JSON-RPC 2.0 over MQTT
  26. ┌──────────────▼─────────────┐
  27. │ Shell Server │
  28. │ │
  29. │ Executor (session级) │
  30. │ ├─ cwd │
  31. │ ├─ Exec(cmd) │
  32. │ ├─ Interrupt() │
  33. │ │
  34. │ process group (pgid) │
  35. │ └─ kill(-pgid, SIGINT) │
  36. └────────────────────────────┘
  37. 6,执行流程图:
  38. ┌──────────────────────────────────────────┐
  39. │ Remote Client │
  40. │ (Web / App / CLI 运维平台) │
  41. └───────────────┬──────────────────────────┘
  42. │ JSON-RPC 2.0
  43. │ - shell.execute
  44. │ - shell.interrupt
  45. │ - ping
  46. v
  47. ┌──────────────────────────────────────────┐
  48. │ MQTT Broker │
  49. │ (QoS1 / KeepAlive / Reconnect) │
  50. └───────────────┬──────────────────────────┘
  51. │ MQTT Message
  52. │ Topic: /yfkj/device/rpc/{imei}/cmd
  53. v
  54. ┌──────────────────────────────────────────┐
  55. │ sshd / MQTTCoupler │
  56. │ │
  57. │ Transport & RPC Adapter Layer │
  58. │ --------------------------------------- │
  59. │ - MQTT 连接管理 │
  60. │ - JSON-RPC 解析 / 校验 │
  61. │ - 方法分发 (Method Dispatch) │
  62. │ │
  63. │ RPC → 本地语义映射 │
  64. │ --------------------------------------- │
  65. │ shell.execute → Executor.Exec() │
  66. │ shell.interrupt → Executor.Interrupt() │
  67. │ │
  68. └───────────────┬──────────────────────────┘
  69. │ 串行 / 单 Session
  70. v
  71. ┌──────────────────────────────────────────┐
  72. │ shell.Executor │
  73. │ │
  74. │ Session State Layer (≈ SSH Session) │
  75. │ --------------------------------------- │
  76. │ State: │
  77. │ - cwd : 当前工作目录 │
  78. │ - pg : 当前前台进程组 │
  79. │ │
  80. │ Built-in Commands │
  81. │ --------------------------------------- │
  82. │ - cd │
  83. │ - pwd │
  84. │ │
  85. │ Control Interface │
  86. │ --------------------------------------- │
  87. │ Exec() : 启动命令 │
  88. │ Interrupt() : Ctrl+C (SIGINT) │
  89. │ │
  90. └───────────────┬──────────────────────────┘
  91. │ 单次命令执行
  92. v
  93. ┌──────────────────────────────────────────┐
  94. │ executeInternal │
  95. │ │
  96. │ Process Lifecycle Layer │
  97. │ --------------------------------------- │
  98. │ - fork/exec │
  99. │ - 新进程组 (setpgid) │
  100. │ - stdout / stderr 限流 │
  101. │ - 超时控制 (context timeout) │
  102. │ - SIGTERM → SIGKILL │
  103. │ │
  104. └───────────────┬──────────────────────────┘
  105. │ MQTT Message
  106. | Topic: /yfkj/device/rpc/{imei}/ack
  107. v
  108. ┌──────────────────────────────────────────┐
  109. │ Linux Kernel │
  110. │ │
  111. │ - Process Group │
  112. │ - Signal Delivery │
  113. │ - Exit Status │
  114. └──────────────────────────────────────────┘
  115. 8, 取消流程图:Ctrl+C
  116. Remote Client
  117. │ shell.execute
  118. v
  119. ┌───────────────┐
  120. │ sshd │
  121. └──────┬────────┘
  122. v
  123. ┌───────────────────────────┐
  124. │ shell.Executor │
  125. │ │
  126. │ Exec(): │
  127. │ - 设置 p.Dir = cwd │
  128. │ - 注册前台进程组 pg │
  129. │ │
  130. └──────┬────────────────────┘
  131. v
  132. ┌───────────────────────────┐
  133. │ executeInternal │
  134. │ │
  135. │ - Start cmd │
  136. │ - setpgid │
  137. │ - onStart(pg) │◄──────┐
  138. │ │ │
  139. │ - wait / timeout │ │
  140. └──────┬────────────────────┘ │
  141. │ │
  142. v │
  143. Command Running │
  144. Remote Client Ctrl+C │
  145. │ │
  146. │ shell.interrupt │
  147. v │
  148. ┌───────────────┐ │
  149. │ sshd │ │
  150. └──────┬────────┘ │
  151. │ │
  152. v │
  153. ┌───────────────────────────┐ │
  154. │ Executor.Interrupt() │ │
  155. │ → SIGINT to -pgid │───────┘
  156. └───────────────────────────┘