Ich bin neu bei GRPC und kann ein Problem nicht lösen. Ist es möglich, eine Protobuff-Datei zu erstellen, wenn die Anwendung bereits ausgeführt wird?
Ich erhalte beispielsweise ein json
vom Benutzer wie folgt:
"protobuf_file": "protobuf.proto", // File will be also recieved from user "service_name": "Unary", "method_name": "GetServerResponse", "request_data_serializer_name": "MessageRequest", "body": "grpc_request_data.json", // File will be also recieved from user
Hier habe ich eine .proto
-Datei, einen Dienstnamen, eine Methode und eine Nachricht sowie einen weiteren JSON mit Daten zum Füllen der Nachricht.
Jetzt muss ich die Verbindung öffnen und die benötigte Methode mit den bereitgestellten Daten aufrufen.
TY!
PS .proto
Die Datei (aus der Anleitung zur Beschaffung) lautet:
syntax = "proto3"; package protobuf_all_modes; service Unary { rpc GetServerResponse(MessageRequest) returns (MessageResponse) {} } message MessageRequest { string message = 1; } message MessageResponse { string message = 1; int32 random_int32 = 2; }
Das zweite json
wird sein:
{ "message": "hello World!" }
Ich weiß nicht, wo ich nach einer Lösung suchen soll. Über Vorschläge wäre ich sehr dankbar.
Wenn jemand das gleiche Problem hat, gibt es eine wirklich gute Bibliothek – https://pkg.go.dev/github.com/jhump/[ email protected] /dynamic und ein Unterpakethttps://pkg.go.dev/github. com/jhump/[email protected]/dynamic/grpcdynamic
Der Codeausschnitt wäre:
parser
func NewGrpcObject(operation *BaseOperation) *GrpcObject { fns, err := protoparse.ResolveFilenames([]string{"./"}, operation.ProtoFile) // prase .proto file if err != nil { log.Error(err) } parser := protoparse.Parser{} fds, err := parser.ParseFiles(fns...) if err != nil { log.Error(err) } descriptor := fds[0] // In my case there will be only one .proto pkg := descriptor.GetPackage() serviceDescriptor := descriptor.FindService(pkg + "." + operation.ServiceName) // name of service descriptor will be with package name first methodDescriptor := serviceDescriptor.FindMethodByName(operation.MethodName) requestDescriptor := methodDescriptor.GetInputType() // You can get types for request and response responseDescriptor := methodDescriptor.GetOutputType() return &GrpcObject{ RequestDesc: requestDescriptor, MethodDesc: methodDescriptor, ResponseDesc: responseDescriptor, } }
caller
// connect conn, _ := grpc.Dial(operation.Host, grpc.WithTransportCredentials(credentials.NewTLS(c.TLSClientConfig.NewTLSConfig()))) stub = grpcdynamic.NewStub(conn) // call message := dynamic.NewMessage(operation.GrpcObject.RequestDesc) // from parser message.UnmarshalJSON(operation.Body) // here a JSON to fill message resp, err := stub.InvokeRpc(ctx, operation.GrpcObject.MethodDesc, message) if err != nil { // handle err } respMessage := dynamic.NewMessage(operation.GrpcObject.ResponseDesc) // descriptor from parser respMessage.ConvertFrom(resp) // convert message from raw response
Das obige ist der detaillierte Inhalt vonGO und GRPC: Protobuff-Klassen „on the fly' erstellen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!