20251222 - 轻量级通信协议 JsonRPC
哪怕这个函数不在我这台机器(或这个进程)的内存里,我也能像调用本地函数一样调用它。本地调用:你在main.cpp里写,程序直接跳转到那个内存地址执行。RPC调用前台(顾客):想吃“宫保鸡丁”(想执行),前台也算是一个进程。后台(厨师):在厨房里(另一个进程),前台(顾客)进不去。RPC机制:前台写一张单子塞进窗口,后台拿到单子,做好菜,再把菜(结果)递出来。错觉:对前台来说,感觉就像自己直接让菜变
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 开发板上,架构是这样的:

具体的交互流程:
-
用户点击:你在 Qt 界面上点击了“打开 LED”按钮。
-
打包:Qt 程序内部将这个操作打包成一个字符串:
{“jsonrpc”: “2.0”, “method”: “set_led”, “params”: [1], “id”: 1}
-
发送:Qt 程序通过 TCP Socket(比如连接到本地
127.0.0.1:8888)把这个字符串发出去。 -
接收与执行:后台程序一直在监听端口,收到了字符串。它用 JSON 库解析,发现你要调用
set_led,参数是1。于是它调用底层的write(fd, ...)去操作驱动。 -
回复:后台程序操作成功,生成回复字符串:
{“jsonrpc”: “2.0”, “result”: 0, “id”: 1}
并通过 Socket 发回给 Qt。
-
更新UI:Qt 收到回复,确认操作成功,把按钮状态改为“已开启”。
第四部分:为什么要这么麻烦?
你可能会问:“我在 Qt 里直接 open /dev/led 不行吗?为什么非要搞两个进程还通过网络说话?”
前后台分离,这是一个非常高级的系统架构思维,好处如下:
- 解耦(防崩溃):
- 如果直接写:Qt 界面代码里混杂着底层驱动代码。如果驱动读取出了 Bug(比如野指针),整个 Qt 界面就会卡死甚至闪退,用户体验极差。
- 用 JsonRPC:UI 只是发命令。如果后台逻辑进程挂了,UI 还是活着的,可以提示用户“连接断开”,甚至可以自动重启后台服务。
- 分工明确:
- 做 UI 的同学(Qt)只管界面好看,不用懂底层驱动。
- 做 驱动 的同学(C语言)只管硬件控制,不用懂怎么画按钮。
- 他们只需要约定好 JSON 的格式(API文档)即可并行开发。
- 语言无关性:
- 后台必须用 C/C++ 操作硬件。
- 前台呢?以后你想把界面换成 Python (PyQt) 甚至 Web (HTML/JS) 网页端,后台程序一行代码都不用改!因为发过来的都是 JSON 字符串,谁发来的都一样。
总结
- JsonRPC = JSON (快递包裹格式) + RPC (远程遥控)。
- 它是前后台程序之间的“普通话”。
Web (HTML/JS) 网页端,后台程序一行代码都不用改!因为发过来的都是 JSON 字符串,谁发来的都一样。
总结
- JsonRPC = JSON (快递包裹格式) + RPC (远程遥控)。
- 它是前后台程序之间的“普通话”。
- 它让你在写代码时,感觉像是在调用本地函数,实际上是发了一个网络请求去让别人干活。
更多推荐

所有评论(0)