一、GRPC使用JS
通过`grpc`的`@grpc/proto-loader`包,我们可以方便地将`.proto`文件生成的`service`数据结构转换为`service`的构造函数。并且可以使用`@grpc/grpc-js`包直接连接`grpc`服务并调用服务方法,使用起来非常便捷。
下面是一个简单的使用示例:
// 定义message和service
syntax = "proto3";
package proto;
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
// 加载proto文件
const PROTO_PATH = path.join(__dirname, '../proto/helloworld.proto');
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld;
// 创建客户端连接
const client = new hello_proto.Greeter('localhost:50051', grpc.credentials.createInsecure());
// 调用服务方法
client.SayHello({name: 'world'}, (err, response) => {
console.log(response);
});
二、GRPC使用Msgpack
默认情况下,`grpc`使用`Protobuf`作为序列化/反序列化协议,但是用户可以通过实现自定义`serializer`替换默认的`serializer`。
这里我们介绍使用`msgpack`替代`protobuf`的示例:
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const msgpack = require('msgpack5')();
// 定义序列化、反序列化函数
const serialize = (value) => {
return msgpack.encode(value).toString('binary');
};
const deserialize = (bytes) => {
return msgpack.decode(bytes);
};
// 加载proto文件
const protoDef = protoLoader.loadSync('example.proto');
const protoPackage = grpc.loadPackageDefinition(protoDef);
// 替换默认的protobuf serializer/deserializer
const options = {
binaryAsBase64: false,
serialize: serialize,
deserialize: deserialize
};
const client = new protoPackage.example.ExampleService('localhost:8888', grpc.credentials.createInsecure(), options);
// 调用服务方法
client.exampleMethod({}, (err, response) => {
console.log(response);
});
三、GRPC使用C++
使用`grpc`的C++实现非常方便简单,只需要安装`grpc`的C++依赖库,然后使用C++代码即可调用服务方法。
下面是一个简单的使用示例:
void RunService() {
echo::EchoImpl service;
ServerBuilder builder;
builder.AddListeningPort("0.0.0.0:50051", grpc::InsecureServerCredentials());
builder.RegisterService(&service);
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait();
}
int main(int argc, char* argv[]) {
grpc::EnableDefaultHealthCheckService(true);
grpc::reflection::InitProtoReflectionServerBuilderPlugin();
RunService();
return 0;
}
四、GRPC使用什么协议
`grpc`默认使用`protobuf`作为序列化/反序列化协议,但是用户可以通过自定义`serializer`替换默认的协议。
五、GRPC使用域名
可以通过域名进行`grpc`服务的调用,只需要在客户端的`new Client`语句中指定域名即可。
const client = new helloworld.Greeter('localhost:50051', grpc.credentials.createInsecure());
六、GRPC使用教程
推荐阅读grpc的官方文档https://grpc.io/docs/languages/js/basics/
七、GRPC使用场景
`grpc`适合分布式系统、微服务架构以及数据通信频繁的场景。`grpc`优势在于使用`protobuf`进行序列化和反序列化,效率非常高。
八、GRPC使用案例
实时在线教育
在线教育需要考虑实时性,`grpc`可以通过双向流式RPC解决请求间数据传输的实时性问题,并且使用高效的`protobuf`序列化协议,可以优化数据传输效率。
金融数据传输
金融行业数据量大、传输频繁、高效稳定的通信方式,非常适合使用`grpc`。
九、GO使用GRPC
Go语言作为Google开发的语言,支持grpc,非常适合使用grpc进行分布式服务的开发。
下面是一个简单的示例,在Go中调用`grpc`服务:
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"net"
pb "path/to/proto"
)
type server struct{}
func (s *server) Hello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
return &pb.HelloResponse{Message: "Hello " + in.Name}, nil
}
func main() {
lis, err := net.Listen("tcp", "localhost:50051")
if err != nil {
fmt.Printf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
if err := s.Serve(lis); err != nil {
fmt.Printf("failed to serve: %v", err)
}
}