一、protobuf rpc原理
protobuf rpc是一种客户端-服务器协议,它利用protobuf消息作为数据传输和协议状态的编码方式。它的实现基于protobuf语法生成的代码和多种传输机制。
protobuf rpc使用不同的接口作为服务器和客户端之间通信的协议,以实现远程过程调用(RPC)。这些接口的定义可以由IDL(接口定义语言)表示。protobuf官方维护的IDL包括proto-rpc和grpc。
protobuf rpc提供了一种简单而且有效的方法,让不同语言开发的应用之间轻松相互通信。
二、protobuf rpc函数重名
为避免函数名重复,对于每个rpc service,每个rpc函数都有一个唯一的名称。如果protobuf定义文件中出现重名的函数,protobuf编译器会报错。
例如下面的代码,由于SayHello函数重复定义,编译器会报错:
service HelloService { rpc SayHello (HelloRequest) returns (HelloReply) {} rpc SayHello (HelloRequest2) returns (HelloReply2) {} rpc SayHello (HelloRequest) returns (HelloReply) {} }
三、protobuf rpc流程
protobuf rpc流程通常包括以下几个步骤:
- 客户端调用Stub的rpc函数,并将请求参数编码成protobuf消息进行发送。
- 服务器接收客户端请求,并将消息反序列化成请求参数。
- 服务器执行请求处理函数,并将响应结果编码成protobuf消息返回给客户端。
- 客户端接收到服务器响应,并将protobuf消息反序列化成响应结果。
下面是一个简单的例子:
//客户端代码 HelloRequest request = HelloRequest.newBuilder().setName("Tom").build(); HelloReply reply = stub.sayHello(request); //服务器端代码 @Override public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) { String name = request.getName(); responseObserver.onNext(HelloReply.newBuilder().setMessage("Hello " + name).build()); responseObserver.onCompleted(); }
四、protobuf rpc参数
protobuf rpc支持的参数类型包括基本数据类型和protobuf消息类型。可以通过定义protobuf消息类型来传递更复杂的数据结构。
例如:
service GreetingService { rpc GreetPerson(Person) returns (Greeting); } message Person { string firstName = 1; string lastName = 2; } message Greeting { string greeting = 1; } //客户端代码 Person person = Person.newBuilder().setFirstName("Tom").setLastName("Jerry").build(); Greeting greeting = stub.greetPerson(person); //服务器端代码 @Override public void greetPerson(Person request, StreamObserver<Greeting> responseObserver) { String greeting = "Hello " + request.getFirstName() + " " + request.getLastName(); responseObserver.onNext(Greeting.newBuilder().setGreeting(greeting).build()); responseObserver.onCompleted(); }
五、protobuf rpc设计
在使用protobuf rpc时,需要考虑以下几点:
- 数据格式:protobuf rpc的可扩展的数据格式使得它比JSON或XML传输数据更加高效。
- 接口定义:IDL的使用可以有效地定义接口,让不同语言的客户端可以轻松地使用相同的接口定义。
- 异步流:protobuf rpc提供了异步流功能,允许客户端和服务器端在传输过程中产生大量的数据流。
六、protobuf rpc多参
protobuf rpc支持多个参数,只需要在服务端函数的参数列表中定义多个参数即可。例如:
service UserService { rpc CreateUser(UserRequest, OtherRequest) returns (UserResponse); } message UserRequest { string name = 1; } message OtherRequest { int32 age = 1; } message UserResponse { int32 userId = 1; }
七、protobuf rpc参数为空
protobuf rpc允许定义参数为空。例如:
service UserService { rpc GetUser(GetUserRequest) returns (UserResponse); rpc DeleteUser(EmptyRequest) returns (EmptyResponse); } message EmptyRequest {} message EmptyResponse {} message GetUserRequest { int32 userId = 1; }
八、protobuf rpc双向通信
protobuf rpc支持双向通信,允许客户端和服务器端在传输过程中可以同时进行读写操作。
以下是一个简单的例子:
service ChatService { rpc Join(ChatJoinRequest) returns (stream ChatMessage); rpc Post(stream ChatMessage) returns (ChatPostResponse); } message ChatJoinRequest { string name = 1; } message ChatMessage { string text = 1; } message ChatPostResponse { int32 messageId = 1; }
在该例子中,Join函数返回一个流(stream)类型的ChatMessage消息列表。Post函数则接收一个消息列表,然后返回响应结果。
双向通信的实现需要借助gRPC框架的支持。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/269842.html