JsonRPC 是目前在嵌入式开发、Web开发中非常流行的一种轻量级通信协议。

为了让你从零基础彻底理解它,我将把它拆解为三个部分:

JSON(数据格式)、RPC(动作机制)以及其结合起来的工作流程

我们用一个**“餐厅点餐”**的生活案例来类比。

第一部分:核心概念拆解

1. 什么是 RPC (Remote Procedure Call)?

**RPC(远程过程调用)**的意思是:哪怕这个函数不在我这台机器(或这个进程)的内存里,我也能像调用本地函数一样调用它。

  • 本地调用:你在 main.cpp 里写 led_control(1),程序直接跳转到那个内存地址执行。
  • RPC调用
    • 前台(顾客):想吃“宫保鸡丁”(想执行 led_control),前台也算是一个进程。
    • 后台(厨师):在厨房里(另一个进程),前台(顾客)进不去。
    • RPC机制:前台写一张单子塞进窗口,后台拿到单子,做好菜,再把菜(结果)递出来。
    • 错觉:对前台来说,感觉就像自己直接让菜变出来了一样,实际上是别人代劳的。
2. 什么是 JSON?

JSON 就是上述那张“单子”的书写格式。

以前大家用 XML(繁琐)或 二进制(人看不懂),现在大家都喜欢用 JSON,因为它既是文本,人能看懂,机器解析也快。

它长这样:

JSON

{
    "name": "dht11",
    "value": 25,
    "is_ok": true
}

它由键值对 (Key-Value) 组成,非常清晰。


第二部分:JsonRPC 是怎么工作的?

JsonRPC 就是:用 JSON 格式写成的“命令单”,通过网络(TCP/Socket)发送给对方,让对方执行函数。

它规定了“单子”上必须写什么内容,主要分两类:请求(Request)响应(Response)

1. 请求格式(前台 -> 后台)

假设前台想让后台“打开LED灯”,前台需要构造这样一个 JSON 字符串发送出去:

JSON

{
    "jsonrpc": "2.0",
    "method": "led_control",
    "params": [1],
    "id": 101
}
  • jsonrpc: 版本号,固定写 “2.0”。
  • method: 最关键的。你要调用的函数名叫什么?(这里是 led_control)。
  • params: 参数。函数需要几个参数?(这里是 [1],表示需要 1 个参数)。
  • id: 订单号
    • 为什么要 ID?因为前台可能一下子发了 10 个指令(开灯、读温度、蜂鸣器…)。
    • 当后台发回结果时,前台需要知道这个结果是对应哪个指令的。
2. 响应格式(后台 -> 前台)

后台收到上面的字符串,解析出函数名和参数,去执行真正的 C 代码 led_control(1),执行完后,给前台回信:

如果成功:

{
    "jsonrpc": "2.0",
    "result": "success",
    "id": 101
}
  • result: 函数的返回值(可以是字符串、数字、对象等)。
  • id: 101。前台一看:“哦,这是我刚才发的那个 101 号订单(开灯)的结果。”

如果失败(比如函数名写错了):

{
    "jsonrpc": "2.0",
    "error": {
        "code": -32601,
        "message": "Method not found"
    },
    "id": 101
}

第三部分:结合你的课程场景

在你的 Linux 开发板上,架构是这样的:

image-20251222010657280

具体的交互流程:
  1. 用户点击:你在 Qt 界面上点击了“打开 LED”按钮。

  2. 打包:Qt 程序内部将这个操作打包成一个字符串:

    {“jsonrpc”: “2.0”, “method”: “set_led”, “params”: [1], “id”: 1}

  3. 发送:Qt 程序通过 TCP Socket(比如连接到本地 127.0.0.1:8888)把这个字符串发出去。

  4. 接收与执行:后台程序一直在监听端口,收到了字符串。它用 JSON 库解析,发现你要调用 set_led,参数是 1。于是它调用底层的 write(fd, ...) 去操作驱动。

  5. 回复:后台程序操作成功,生成回复字符串:

    {“jsonrpc”: “2.0”, “result”: 0, “id”: 1}

    并通过 Socket 发回给 Qt。

  6. 更新UI:Qt 收到回复,确认操作成功,把按钮状态改为“已开启”。


第四部分:为什么要这么麻烦?

你可能会问:“我在 Qt 里直接 open /dev/led 不行吗?为什么非要搞两个进程还通过网络说话?”

前后台分离,这是一个非常高级的系统架构思维,好处如下:

  1. 解耦(防崩溃)
    • 如果直接写:Qt 界面代码里混杂着底层驱动代码。如果驱动读取出了 Bug(比如野指针),整个 Qt 界面就会卡死甚至闪退,用户体验极差。
    • 用 JsonRPC:UI 只是发命令。如果后台逻辑进程挂了,UI 还是活着的,可以提示用户“连接断开”,甚至可以自动重启后台服务。
  2. 分工明确
    • 做 UI 的同学(Qt)只管界面好看,不用懂底层驱动。
    • 做 驱动 的同学(C语言)只管硬件控制,不用懂怎么画按钮。
    • 他们只需要约定好 JSON 的格式(API文档)即可并行开发。
  3. 语言无关性
    • 后台必须用 C/C++ 操作硬件。
    • 前台呢?以后你想把界面换成 Python (PyQt) 甚至 Web (HTML/JS) 网页端,后台程序一行代码都不用改!因为发过来的都是 JSON 字符串,谁发来的都一样。

总结

  • JsonRPC = JSON (快递包裹格式) + RPC (远程遥控)。
  • 它是前后台程序之间的“普通话”。
    Web (HTML/JS) 网页端,后台程序一行代码都不用改!因为发过来的都是 JSON 字符串,谁发来的都一样。

总结

  • JsonRPC = JSON (快递包裹格式) + RPC (远程遥控)。
  • 它是前后台程序之间的“普通话”。
  • 它让你在写代码时,感觉像是在调用本地函数,实际上是发了一个网络请求去让别人干活。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐