Flutter for OpenHarmony:json_rpc_2 比 REST 更轻量的远程调用协议,实现高效的前后端通信(JSON-RPC 2.0 实现) 深度解析与鸿蒙适配指南
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net
前言
在现代软件架构中,RPC (Remote Procedure Call) 无处不在。它允许我们像调用本地函数一样调用远程服务器上的函数。虽然 gRPC 和 REST (HTTP/JSON) 十分流行,但在一些特定场景下,JSON-RPC 2.0 依然是不可替代的标准。
- 轻量级:仅依赖 JSON,无须复杂的 Protobuf 编解码或 HTTP Header 开销。
- 传输无关:可以跑在 WebSocket、TCP Socket、甚至串口(Serial Port)上。
- 广泛支持:以太坊(Ethereum)、比特币(Bitcoin)节点通信全部基于 JSON-RPC。
- 简单明了:人眼可读,调试极其方便。
json_rpc_2 是 Google 官方维护的一个 Dart 库,严格遵循 JSON-RPC 2.0 规范,提供了极高质量的 Client 和 Server 实现。
对于 OpenHarmony 开发者,这意味着你可以轻松地用 Dart 构建与底层硬件(如智能家居网关、工控机)通信的客户端,或者搭建一个极简的微服务 API。
一、核心原理与协议规范
1.1 JSON-RPC 2.0 协议详解
JSON-RPC 的消息体极其简洁。
请求 (Request):
{"jsonrpc":"2.0","method":"subtract","params":[42,23],"id":1}响应 (Response):
{"jsonrpc":"2.0","result":19,"id":1}通知 (Notification):
没有 id 字段,服务端收到后不返回任何结果(Fire-and-Forget)。
{"jsonrpc":"2.0","method":"update","params":[1,2,3,4,5]}错误 (Error):
{"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found"},"id":"1"}json_rpc_2 库完全封装了这些 JSON 细节,让你直接面对 Dart 对象编程。
调用方法 add
序列化
网络传输 TCP/WS
逻辑处理
响应 JSON
返回 Future/结果
Flutter 客户端
json_rpc_2 库
请求明文
服务端
计算结果
二、核心 API 详解
2.1 客户端 (Client)
客户端需要一个 StreamChannel 来传输数据。这个 Channel 可以来自 web_socket_channel(用于 Web),也可以来自 dart:io 的 Socket(用于 TCP)。
import'package:json_rpc_2/json_rpc_2.dart';import'package:web_socket_channel/io.dart';voidmain()async{// 1. 建立连接var socket =IOWebSocketChannel.connect('ws://localhost:4321');// 2. 创建 Clientvar client =Client(socket.cast());// 3. 必须先 listen (启动消息循环)unawaited(client.listen());try{// 4. 发送请求var result =await client.sendRequest('add',[1,2]);print('1 + 2 = $result');// 5. 发送通知 (无返回值) client.sendNotification('log',['Connection established']);}finally{await client.close();}}
2.2 服务端 (Server)
服务端 API 同样简洁。你可以注册方法来处理请求。
import'package:json_rpc_2/json_rpc_2.dart';import'package:shelf/shelf_io.dart'as io;import'package:shelf_web_socket/shelf_web_socket.dart';voidmain(){var handler =webSocketHandler((webSocket){var server =Server(webSocket.cast());// 注册方法 server.registerMethod('add',(Parameters params){var nums = params.asList;return nums[0]+ nums[1];}); server.registerMethod('subtract',(Parameters params){var nums = params.asList;return nums[0]- nums[1];});// 启动监听 server.listen();}); io.serve(handler,'localhost',4321).then((server){print('Serving at ws://${server.address.host}:${server.port}');});}2.3 错误处理
json_rpc_2 会自动抛出 RpcException。你可以捕获具体的错误码。
try{await client.sendRequest('unknown_method');}onRpcExceptioncatch(e){if(e.code ==RpcException.methodNotFound){print('Method not found!');// Code -32601}else{print('Error ${e.code}: ${e.message}');}}
三、OpenHarmony 平台适配实战
在鸿蒙系统(尤其是 IoT 设备)中,TCP 通信比 HTTP 更常见且更高效。我们可以使用 Dart 原生的 Socket 来承载 JSON-RPC。
3.1 基于 TCP Socket 的全双工通信
假设我们有一个运行在鸿蒙开发板上的 Dart 服务端,控制 LED 灯。
// lib/rpc_server.dart (运行在开发板)import'dart:io';import'package:json_rpc_2/json_rpc_2.dart';import'package:stream_channel/stream_channel.dart';voidstartServer()async{// 监听 8080 端口var serverSocket =awaitServerSocket.bind(InternetAddress.anyIPv4,8080);print('Listening on port 8080...');awaitfor(var socket in serverSocket){// 将 Socket 包装为 StreamChannel<String> (UTF-8)var channel = jsonDocument.bind(StreamChannel(socket, socket));var rpcServer =Server(channel);// 注册控制方法 rpcServer.registerMethod('set_led',(Parameters params){ bool on= params['on'].asBool;// 获取命名参数print('Turning LED ${on ? 'ON' : 'OFF'}');// 硬件操作逻辑: GPIO.output(1, on);return{'status':'ok','led':on};}); rpcServer.listen();}}3.2 客户端控制 App (Flutter)
// lib/rpc_client.dartimport'dart:io';import'package:json_rpc_2/json_rpc_2.dart';import'package:stream_channel/stream_channel.dart';classIotController{Client? _client;Future<void>connect(String ip)async{var socket =awaitSocket.connect(ip,8080);// 创建双向通道var channel = jsonDocument.bind(StreamChannel(socket, socket)); _client =Client(channel); _client!.listen();// 启动循环}Future<void>toggleLed(bool on)async{if(_client ==null|| _client!.isClosed)throwException('Not connected');// 调用远程方法// 虽然是异步网络请求,写起来就像本地函数调用try{var response =await _client!.sendRequest('set_led',{'on':on});print('Response: $response');}catch(e){print('RPC Error: $e');}}}这个例子展示了 json_rpc_2 最强大的能力:Transport Agnostic (传输无关性)。只要你能提供一个 StreamChannel,不管是 TCP、WebSocket,甚至是 Bluetooth RFCOMM,它都能跑起来。

四、高级进阶:批量请求 (Batch Request)
JSON-RPC 2.0 支持一次发送多个请求,常用于初始化大量数据。
// 客户端 client.withBatch((){ client.sendRequest('add',[1,1]); client.sendRequest('add',[2,2]); client.sendNotification('log',['Batch test']);}).then((results){// results 包含所有返回结果print(results);// [2, 4, null] });这对于移动网络环境极其友好,减少了 RTT(往返时延)。
五、总结
json_rpc_2 是 Dart 生态中被严重低估的一个库。它虽然看起来简单,但却是构建高可靠、低延迟、跨语言通信系统的基石。
与 gRPC 相比,它无需生成代码,调试只需 print;与 REST 相比,它支持全双工 Notification 推送。
对于 OpenHarmony 开发者,特别是涉及 硬件交互、即时通讯、区块链交互 的场景,JSON-RPC 是你的不二之选。
最佳实践:
- 超时控制:在
sendRequest后加上.timeout(Duration(seconds: 5)),防止网络挂死。 - 错误定义:在服务端统一定义业务错误码(如
-32001代表硬件故障),客户端据此做 UI 提示。