GRPC是一種高效、輕量級(jí)的RPC框架,它對(duì)消息的序列化和反序列化進(jìn)行了優(yōu)化,采用了Google開(kāi)源的protobuf作為默認(rèn)的消息格式。GRPC還支持將消息格式轉(zhuǎn)換為JSON格式,并提供了相應(yīng)的編解碼器。
要使用JSON格式,需要在proto文件中指定:
syntax = "proto3"; package example; import "google/protobuf/json_format.proto"; message MyRequest { string name = 1; } message MyResponse { string message = 1; } service MyService { rpc MyMethod (MyRequest) returns (MyResponse) { option (google.protobuf.json_format.json_spec) = true; } }
在上面的proto文件中,我們?cè)黾恿艘粋€(gè)option聲明,指定了將消息格式轉(zhuǎn)換為JSON格式。這個(gè)聲明會(huì)在編譯proto文件時(shí)生成相應(yīng)的代碼。
在客戶端代碼中,使用JSON格式時(shí)需要手動(dòng)創(chuàng)建JSON格式的編解碼器:
import io.grpc.protobuf.ProtoJsonUtil; MyRequest request = MyRequest.newBuilder().setName("John").build(); String json = ProtoJsonUtil.toJson(request); MyRequest requestFromJson = ProtoJsonUtil.fromJson(json, MyRequest.class);
上面的代碼將請(qǐng)求對(duì)象轉(zhuǎn)換為JSON格式,并從JSON格式轉(zhuǎn)換回請(qǐng)求對(duì)象。需要注意的是,使用JSON格式可能會(huì)帶來(lái)性能上的損失,因?yàn)镴SON格式相比protobuf格式要更加冗長(zhǎng)。
在服務(wù)端代碼中,使用JSON格式時(shí)需要在處理請(qǐng)求時(shí)將JSON格式的消息轉(zhuǎn)換為protobuf格式的消息,處理完后再將protobuf格式的消息轉(zhuǎn)換為JSON格式的消息:
import com.google.protobuf.util.JsonFormat; public void myMethod(MyRequest request, StreamObserverresponseObserver) { try { String json = JsonFormat.printer().print(request); // process request in protobuf format MyResponse response = MyResponse.newBuilder().setMessage("Hello " + request.getName()).build(); String jsonResponse = JsonFormat.printer().print(response); responseObserver.onNext(ProtoJsonUtil.fromJson(jsonResponse, MyResponse.class)); responseObserver.onCompleted(); } catch (Exception e) { responseObserver.onError(e); } }
上面的代碼將請(qǐng)求消息格式轉(zhuǎn)換為JSON格式,處理請(qǐng)求后將響應(yīng)消息格式轉(zhuǎn)換為JSON格式并發(fā)送回客戶端。需要注意的是,在處理消息時(shí)要捕獲異常并將異常信息發(fā)送給客戶端。