Flutter gRPC通信插件cln_grpc的使用
Flutter gRPC通信插件cln_grpc的使用
lndart.cln_grpc
![](https://github.com/dart-lightning/icons/raw/main/main/res/mipmap-xxxhdpi/ic_launcher.png)
** :dart: Dart GRPC客户端用于核心闪电 :dart: **
项目主页
目录
- 介绍
- 如何使用
- 如何贡献
- 许可证
介绍
一个帮助Dart GRPC客户端连接到核心闪电的库。
为什么使用cln_grpc?
cln_grpc 库是一个带有通用接口的 GRPC 包装器,它便于使用 Dart 和 Flutter 与核心闪电进行交互。它可以直接访问核心闪电节点并执行一些操作,例如调用通过 GRPC 接口支持的 RPC 方法。
如何使用
如何连接到核心闪电使用 cln_grpc
要连接到 gRPC 服务器,我们需要服务器的端口、主机和服务器凭证。
在这个库中,唯一必需的参数是证书路径以供认证,还有一些可选参数,如:
host
(默认为 “localhost”):服务器运行的位置,这需要与 tls 证书中声明的一致。port
(默认为 8001):gRPC 服务器运行的位置,指定为核心闪电选项中的grpc-port
。authority
(默认为 “localhost”)channelCredentials
:控制 ClientChannel 上的 TLS 安全设置的选项。
要初始化客户端并与其服务器建立连接,我们可以这样声明客户端:
var client = GRPCClient(rootPath: "<path_to_certificates>");
如何调用方法
有几种方法可以调用方法:
1. 使用解析函数调用 getinfo
var response = await client.getInfo(onDecode: (Map<String, dynamic> json) => json);
print('Response from server\n$response');
2. 使用泛型调用 <T, R>
方法
这里我们需要将请求方法序列化以便将其从 JSON 转换为 Map。
class ListTransactionProxy extends Serializable {
ListtransactionsRequest proxy;
ListTransactionProxy(this.proxy);
factory ListTransactionProxy.build() =>
ListTransactionProxy(ListtransactionsRequest());
[@override](/user/override)
Map<String, dynamic> toJSON() => proxy.toProto3Json() as Map<String, dynamic>;
[@override](/user/override)
T as<T>() => proxy as T;
}
在序列化请求后,我们调用泛型 “call” 方法,并提供所需的参数如下:
var transactionList =
await client.call<ListTransactionProxy, ListtransactionsResponse>(
method: "listtransactions", params: ListTransactionProxy.build());
print("Transactions of node");
print(transactionList.transactions);
3. 直接访问 stub 以调用未实现的方法(跳过库架构)
var forwardsList = await client.stub.listForwards(ListforwardsRequest());
print("Forwards of node");
print(forwardsList.forwards);
关闭客户端连接
关闭 gRPC 客户端连接非常简单,只需调用 close 方法即可:
client.close();
如何贡献
构建系统
您可以使用 make 文件确保您的代码可以通过 CI 的代码检查:
Make 文件包含以下目标:
make
:格式化、分析和编译代码;make fmt
:格式化和分析代码;make check
:运行单元测试(如果有的话)
阅读 Hacking 指南 以了解如何管理更改请求(Pull 请求)的工作流程。
生成代码
为了更新核心闪电生成的新 proto 文件,我们需要复制新文件到 proton 并生成一些 Dart 文件,使用以下命令更新 Dart 代码:
需求:
- 升级 protobuf 版本等于或高于 版本 3.15。
- 添加
protoc-gen-dart
到您的路径。 - 或者使用此命令
protoc --dart_out=grpc:./lib/src/ --plugin=protoc-gen-dart=$HOME/.pub-cache/bin/protoc-gen-dart ./protos/primitives.proto ./protos/node.proto
带有插件标志来生成.pb.dart
文件。
以下是生成 .pb.dart
文件的步骤:
- 在项目的根目录。
- 运行此命令
make gen
来为/primitives.proto
和/node.proto
生成.pb.dart
文件。 - 将
./lib/src/protos
重命名为./lib/src/generated
。
许可证
![](https://opensource.org/files/osi_keyhole_300X300_90ppi_0.png)
Copyright 2022 Vincenzo Palazzo <vincenzopalazzodev@gmail.com>. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
示例代码
import 'package:cln_common/cln_common.dart';
import 'package:cln_grpc/cln_grpc.dart';
import 'package:fixnum/fixnum.dart';
class ListTransactionProxy extends Serializable {
ListtransactionsRequest proxy;
ListTransactionProxy(this.proxy);
factory ListTransactionProxy.build() =>
ListTransactionProxy(ListtransactionsRequest());
[@override](/user/override)
Map<String, dynamic> toJSON() => proxy.toProto3Json() as Map<String, dynamic>;
[@override](/user/override)
T as<T>() => proxy as T;
}
class PayProxy extends Serializable {
PayRequest proxy;
PayProxy(this.proxy);
factory PayProxy.build({required String invoice, Amount? amount}) =>
PayProxy(PayRequest(bolt11: invoice, amountMsat: amount));
[@override](/user/override)
Map<String, dynamic> toJSON() => proxy.toProto3Json() as Map<String, dynamic>;
[@override](/user/override)
T as<T>() => proxy as T;
}
Future<void> main(List<String> args) async {
var client = GRPCClient(rootPath: args[0]);
/// 使用直接方法调用
var response = await client.getInfo(
params: GetinfoRequest(), onDecode: (jsonResponse) => (jsonResponse));
print('Response from server\n$response');
/// 使用泛型调用
var transactionList =
await client.call<ListTransactionProxy, ListtransactionsResponse>(
method: "listtransactions", params: ListTransactionProxy.build());
print("Transactions of node");
print(transactionList.transactions);
/// 使用 stub 调用不同方法
var forwardsList = await client.stub.listForwards(ListforwardsRequest());
print("Forwards of node");
print(forwardsList.forwards);
/// 使用代理进行自定义调用以添加动态输入
Int64 msat = Int64(1000);
Amount amount = Amount();
amount.msat = msat;
String boltString = args[1];
var pay = await client.call<PayProxy, PayResponse>(
method: "pay", params: PayProxy.build(invoice: boltString));
print(pay.amountMsat.msat);
client.close();
}
更多关于Flutter gRPC通信插件cln_grpc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter gRPC通信插件cln_grpc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,关于在Flutter项目中使用cln_grpc
插件来实现gRPC通信,下面是一个基本的示例代码,展示了如何设置和使用该插件进行gRPC调用。
首先,确保你已经在Flutter项目中添加了cln_grpc
依赖。在你的pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter:
sdk: flutter
cln_grpc: ^最新版本号 # 替换为实际的最新版本号
然后运行flutter pub get
来安装依赖。
接下来,你需要定义你的gRPC服务和消息。通常,你会有一个.proto
文件来描述这些。例如,假设你有一个简单的helloworld.proto
文件:
syntax = "proto3";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
使用protoc
编译器和grpc-dart
插件生成Dart代码:
protoc --dart_out=grpc:./lib/src/proto -I=. helloworld.proto
确保你已经安装了protoc-gen-dart
插件。生成的Dart文件应该放在lib/src/proto
目录下。
现在,你可以在Flutter项目中使用cln_grpc
来调用这个gRPC服务。以下是一个完整的示例:
- 创建gRPC客户端
// lib/src/grpc_client.dart
import 'package:cln_grpc/cln_grpc.dart';
import 'package:grpc/grpc.dart';
import 'package:your_app/src/proto/helloworld_pb.dart' as hw; // 导入生成的proto文件
class GrpcClient {
final Channel channel;
hw.GreeterClient? greeterClient;
GrpcClient(String host, int port) {
channel = ClientChannel.connect(Uri.parse("$host:$port"),
options: ChannelOptions(
credentials: ChannelCredentials.insecure(),
),
);
greeterClient = hw.GreeterClient(channel);
}
Future<String> sayHello(String name) async {
final request = hw.HelloRequest()..name = name;
final reply = await greeterClient!.sayHello(request, options: CallOptions());
return reply.message!;
}
void shutdown() {
channel.shutdown();
}
}
- 使用gRPC客户端
// lib/main.dart
import 'package:flutter/material.dart';
import 'package:your_app/src/grpc_client.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter gRPC Example'),
),
body: Center(
child: MyHomePage(),
),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState create
State ()String =>? _ responseMy;HomePage
State
();
@}override
classvoid _ initMyStateHomePage()State { extends State<MyHomePage> {
late GrpcClient grpcClient;
super.initState();
grpcClient = GrpcClient('localhost', 50051); // 替换为你的gRPC服务器地址和端口
_callGrpcService();
}
@override
void dispose() {
grpcClient.shutdown();
super.dispose();
}
Future<void> _callGrpcService() async {
try {
String result = await grpcClient.sayHello('World');
setState(() {
response = result;
});
} catch (e) {
print('Error calling gRPC service: $e');
}
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('gRPC Response:'),
Text(response ?? 'Loading...'),
],
);
}
}
这个示例展示了如何在Flutter中使用cln_grpc
插件来调用一个简单的gRPC服务。请注意,你需要运行一个gRPC服务器来响应这些请求,并且确保服务器和客户端使用的.proto
文件是匹配的。
此外,实际项目中可能需要处理更多的错误和异常情况,以及更复杂的UI逻辑。这个示例仅用于展示基本的用法。