最近了解到了 gRPC 的相关内容, 这一篇就写在用法和概念上的相关东西,以 Dart 语言来做代码示例。
brew install protobuf
pub global activate protoc_plugin
export PATH="$PATH":"$HOME/.pub-cache/bin"
让我们新建一个 Dart 工程,在其pusepc.yaml
里添加依赖:
dependencies:
protobuf: ^2.0.0
grpc: ^3.0.0
然后我们就可以开始了。
在 lib 文件夹下创建 protos (名称随意)文件夹,然后创建helloworld.proto
用于写我们的代码:
// helloworld.proto
syntax = "proto3";
package helloworld;
service Greeter{
rpc SayHello(HelloRequest) returns (HelloReply){}
}
message HelloRequest{
string name = 1;
}
message HelloReply{
string message = 1;
}
开头我们声明了使用的是 proto3 版本,然后定义了Greeter
服务,并声明了一个 rpc 接口SayHello
,请求的参数是HelloRequest
,返回的参数是HelloReply
。
在 lib 目录下,我们新建一个 src/generated 文件夹,用于存放我们待会要生成的文件。
然后命令行进入我们的 lib 目录下,执行命令:
protoc --dart_out=grpc:src/generated -Iprotos protos/helloworld.proto
这样 generated 文件夹下就会生成相应的文件:
helloworld.pbjson.dart
helloworld.pbgrpc.dart
helloworld.pbenum.dart
helloworld.pb.dart
同样地在 lib 目录下我们创建 src/bin 目录来写我们的客户端和服务端。
客户端:
// client.dart
import 'package:grpc/grpc.dart';
import 'package:grpc_learning/src/generated/helloworld.pbgrpc.dart';
void main() async {
final channel = ClientChannel(
'localhost',
port: 50051,
options: ChannelOptions(
credentials: ChannelCredentials.insecure(),
codecRegistry:
CodecRegistry(codecs: const [GzipCodec(), IdentityCodec()]),
),
);
final stub = GreeterClient(channel);
final name = 'world';
try {
final response = await stub.sayHello(HelloRequest()..name = name);
print('Greeter client received: ${response.message}');
} catch (e) {
print('error = ${e.toString()}');
}
await channel.shutdown();
}
服务端:
// server.dart
import 'package:grpc/grpc.dart';
import 'package:grpc/src/server/call.dart';
import 'package:grpc_learning/src/generated/helloworld.pbgrpc.dart';
class GreeterService extends GreeterServiceBase {
@override
Future<HelloReply> sayHello(ServiceCall call, HelloRequest request) async {
return HelloReply()..message = 'I got it ${request.name}';
}
}
void main() async {
final server = Server([GreeterService()]);
await server.serve(port: 50051);
print('Server listening on port ${server.port}...');
}
接下来我们就可以开启两个终端,来分别运行客户端和服务端了,使用dart server.dart
和dart client.dart
来执行。
执行结果:
// 服务端
Server listening on port 50051...
// 客户端
Greeter client received: I got it world
这样就完成了一个 gRPC 的客户端与服务端通信的 Demo。